This import syncs to the widevine git repostiory change commit ab3e1e43642cf36900f55169597a33f222709fdb Change-Id: I3a6f1e2969e5fe7ed1ca12f90b0eb0a3b7899835
603 lines
25 KiB
C++
603 lines
25 KiB
C++
// Copyright 2013 Google Inc. All Rights Reserved.
|
|
|
|
#include <errno.h>
|
|
#include <getopt.h>
|
|
|
|
#include "config_test_env.h"
|
|
#include "gtest/gtest.h"
|
|
#include "license_request.h"
|
|
#include "log.h"
|
|
#include "string_conversions.h"
|
|
#include "url_request.h"
|
|
#include "wv_cdm_constants.h"
|
|
#include "wv_content_decryption_module.h"
|
|
|
|
namespace {
|
|
// Default license server, can be configured using --server command line option
|
|
// Default key id (pssh), can be configured using --keyid command line option
|
|
std::string g_client_auth;
|
|
wvcdm::KeyId g_key_id;
|
|
wvcdm::CdmKeySystem g_key_system;
|
|
std::string g_license_server;
|
|
std::string g_port;
|
|
wvcdm::KeyId g_wrong_key_id;
|
|
int g_use_full_path = 0; // cannot use boolean in getopt_long
|
|
} // namespace
|
|
|
|
namespace wvcdm {
|
|
|
|
typedef struct DecryptionData {
|
|
bool is_encrypted;
|
|
wvcdm::KeyId key_id;
|
|
std::vector<uint8_t> encrypt_data;
|
|
std::vector<uint8_t> iv;
|
|
size_t block_offset;
|
|
std::vector<uint8_t> decrypt_data;
|
|
} DecryptionData;
|
|
|
|
class WvCdmRequestLicenseTest : public testing::Test {
|
|
public:
|
|
WvCdmRequestLicenseTest() {}
|
|
~WvCdmRequestLicenseTest() {}
|
|
|
|
protected:
|
|
void GenerateKeyRequest(const std::string& key_system,
|
|
const std::string& init_data) {
|
|
wvcdm::CdmAppParameterMap app_parameters;
|
|
EXPECT_EQ(decryptor_.GenerateKeyRequest(session_id_,
|
|
init_data,
|
|
kLicenseTypeStreaming,
|
|
app_parameters,
|
|
&key_msg_), wvcdm::KEY_MESSAGE);
|
|
}
|
|
|
|
void GenerateRenewalRequest(const std::string& key_system,
|
|
const std::string& init_data) {
|
|
// TODO application makes a license request, CDM will renew the license
|
|
// when appropriate.
|
|
wvcdm::CdmAppParameterMap app_parameters;
|
|
EXPECT_EQ(decryptor_.GenerateKeyRequest(session_id_,
|
|
init_data,
|
|
kLicenseTypeStreaming,
|
|
app_parameters,
|
|
&key_msg_), wvcdm::KEY_MESSAGE);
|
|
}
|
|
|
|
// posts a request and extracts the drm message from the response
|
|
std::string GetKeyRequestResponse(const std::string& server_url,
|
|
const std::string& client_auth,
|
|
int expected_response) {
|
|
UrlRequest url_request(server_url + client_auth, g_port);
|
|
|
|
if (!url_request.is_connected()) {
|
|
return "";
|
|
}
|
|
|
|
url_request.PostRequest(key_msg_);
|
|
std::string response;
|
|
int resp_bytes = url_request.GetResponse(response);
|
|
LOGD("response:\r\n%s", response.c_str());
|
|
LOGD("end %d bytes response dump", resp_bytes);
|
|
|
|
// Youtube server returns 400 for invalid message while play server returns
|
|
// 500, so just test inequity here for invalid message
|
|
int status_code = url_request.GetStatusCode(response);
|
|
if (expected_response == 200) {
|
|
EXPECT_EQ(200, status_code);
|
|
} else {
|
|
EXPECT_NE(200, status_code);
|
|
}
|
|
|
|
std::string drm_msg;
|
|
if (200 == status_code) {
|
|
LicenseRequest lic_request;
|
|
lic_request.GetDrmMessage(response, drm_msg);
|
|
LOGV("drm msg: %u bytes\r\n%s", drm_msg.size(),
|
|
HexEncode(reinterpret_cast<const uint8_t*>(drm_msg.data()),
|
|
drm_msg.size()).c_str());
|
|
}
|
|
return drm_msg;
|
|
}
|
|
|
|
void VerifyKeyRequestResponse(const std::string& server_url,
|
|
const std::string& client_auth,
|
|
std::string& init_data,
|
|
bool is_renewal) {
|
|
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);
|
|
}
|
|
else {
|
|
EXPECT_EQ(decryptor_.AddKey(session_id_, resp), wvcdm::KEY_ADDED);
|
|
}
|
|
}
|
|
|
|
wvcdm::WvContentDecryptionModule decryptor_;
|
|
std::string key_msg_;
|
|
std::string session_id_;
|
|
};
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, BaseMessageTest) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
GetKeyRequestResponse(g_license_server, g_client_auth, 200);
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
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);
|
|
GetKeyRequestResponse(g_license_server, g_client_auth, 500);
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, AddKeyTest) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, LicenseRenewal) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
GenerateRenewalRequest(g_key_system, g_key_id);
|
|
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);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
CdmQueryMap query_info;
|
|
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.QueryKeyStatus(session_id_, &query_info));
|
|
|
|
EXPECT_EQ(wvcdm::QUERY_VALUE_STREAMING,
|
|
query_info[wvcdm::QUERY_KEY_LICENSE_TYPE]);
|
|
EXPECT_EQ(wvcdm::QUERY_VALUE_TRUE,
|
|
query_info[wvcdm::QUERY_KEY_PLAY_ALLOWED]);
|
|
EXPECT_EQ(wvcdm::QUERY_VALUE_FALSE,
|
|
query_info[wvcdm::QUERY_KEY_PERSIST_ALLOWED]);
|
|
EXPECT_EQ(wvcdm::QUERY_VALUE_TRUE,
|
|
query_info[wvcdm::QUERY_KEY_RENEW_ALLOWED]);
|
|
|
|
int64_t remaining_time;
|
|
std::istringstream ss;
|
|
ss.str(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]);
|
|
ss >> remaining_time;
|
|
EXPECT_LE(0, remaining_time);
|
|
ss.str(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]);
|
|
ss >> remaining_time;
|
|
EXPECT_LE(0, remaining_time);
|
|
|
|
EXPECT_LE(0, (int)query_info[QUERY_KEY_RENEWAL_SERVER_URL].size());
|
|
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, QueryStatus) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
CdmQueryMap query_info;
|
|
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.QueryStatus(&query_info));
|
|
|
|
EXPECT_EQ(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3,
|
|
query_info[wvcdm::QUERY_KEY_SECURITY_LEVEL]);
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, ClearDecryptionTest) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
// key 1, clear, 256b
|
|
DecryptionData data;
|
|
data.is_encrypted = false;
|
|
data.key_id = wvcdm::a2bs_hex("E02562E04CD55351B14B3D748D36ED8E");
|
|
data.encrypt_data = wvcdm::a2b_hex(
|
|
"9da401105ab8da443e93e6fe089dfc69e00a9a51690d406872f338c5fa7dd3d5"
|
|
"abf8dfd660aaff3e327850a56eedf707c03e2d1a00f9f0371e3e19ea32b13267"
|
|
"7bc083ccbb83e6d9c03794ee97f50081221a8e5eb123f6dfa895e7a971166483"
|
|
"cdadd61cd8d0f859501e750e9d356d57252ecd9f7388459f5470de9d92198c44"
|
|
"0b520055b3b9a1c6b2c9d21e78dce99622d9d031fc7dee28a6d1d6dfb81502eb"
|
|
"463c4c189555f496d9aa529b3f5522e9f46dcf70b2bfe8df47daf02b6a267f93"
|
|
"f80d871786eb4bd7f08f9c52079c034a9534d885ba4c00cbe2234cfbb5205a56"
|
|
"41dd760f83d0f09f27881ad490efa8b99b7ab24b34311a2e8416b1a80d736ad7");
|
|
data.iv = wvcdm::a2b_hex("50a6c61c3f7c2b37e72b0c047000dd4a");
|
|
data.block_offset = 0;
|
|
data.decrypt_data = wvcdm::a2b_hex(
|
|
"9da401105ab8da443e93e6fe089dfc69e00a9a51690d406872f338c5fa7dd3d5"
|
|
"abf8dfd660aaff3e327850a56eedf707c03e2d1a00f9f0371e3e19ea32b13267"
|
|
"7bc083ccbb83e6d9c03794ee97f50081221a8e5eb123f6dfa895e7a971166483"
|
|
"cdadd61cd8d0f859501e750e9d356d57252ecd9f7388459f5470de9d92198c44"
|
|
"0b520055b3b9a1c6b2c9d21e78dce99622d9d031fc7dee28a6d1d6dfb81502eb"
|
|
"463c4c189555f496d9aa529b3f5522e9f46dcf70b2bfe8df47daf02b6a267f93"
|
|
"f80d871786eb4bd7f08f9c52079c034a9534d885ba4c00cbe2234cfbb5205a56"
|
|
"41dd760f83d0f09f27881ad490efa8b99b7ab24b34311a2e8416b1a80d736ad7");
|
|
|
|
std::vector<uint8_t> decrypt_buffer;
|
|
size_t encrypt_length = data.encrypt_data.size();
|
|
decrypt_buffer.resize(encrypt_length);
|
|
|
|
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_,
|
|
data.is_encrypted,
|
|
data.key_id,
|
|
&data.encrypt_data.front(),
|
|
encrypt_length,
|
|
data.iv,
|
|
data.block_offset,
|
|
&decrypt_buffer.front()));
|
|
|
|
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
|
|
decrypt_buffer.begin()));
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, DecryptionTest) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
// key 1, encrypted, 256b
|
|
DecryptionData data;
|
|
data.is_encrypted = true;
|
|
data.key_id = wvcdm::a2bs_hex("E02562E04CD55351B14B3D748D36ED8E");
|
|
data.encrypt_data = wvcdm::a2b_hex(
|
|
"3b2cbde084973539329bd5656da22d20396249bf4a18a51c38c4743360cc9fea"
|
|
"a1c78d53de1bd7e14dc5d256fd20a57178a98b83804258c239acd7aa38f2d7d2"
|
|
"eca614965b3d22049e19e236fc1800e60965d8b36415677bf2f843d50a6943c4"
|
|
"683c07c114a32f5e5fbc9939c483c3a1b2ecd3d82b554d649798866191724283"
|
|
"f0ab082eba2da79aaca5c4eaf186f9ee9a0c568f621f705a578f30e4e2ef7b96"
|
|
"5e14cc046ce6dbf272ee5558b098f332333e95fc879dea6c29bf34acdb649650"
|
|
"f08201b9e649960f2493fd7677cc3abf5ae70e5445845c947ba544456b431646"
|
|
"d95a133bff5f57614dda5e4446cd8837901d074149dadf4b775b5b07bb88ca20");
|
|
data.iv = wvcdm::a2b_hex("4cca615fc013102892f91efee936639b");
|
|
data.block_offset = 0;
|
|
data.decrypt_data = wvcdm::a2b_hex(
|
|
"5a36c0b633b58faf22156d78fdfb608e54a8095788b2b0463ef78d030b4abf82"
|
|
"eff34b8d9b7b6352e7d72de991b599662aa475da355033620152e2356ebfadee"
|
|
"06172be9e1058fa177e223b9fdd191380cff53c3ea810c6fd852a1df4967b799"
|
|
"415179a2276ec388ef763bab89605b9c6952c28dc8d6bf86b03fabbb46b392a3"
|
|
"1dad15be602eeeeabb45070b3e25d6bb0217073b1fc44c9fe848594121fd6a91"
|
|
"304d605e21f69615e1b57db18312b6b948725724b74e91d8aea7371e99532469"
|
|
"1b358bdee873f1936b63efe83d190a53c2d21754d302d63ff285174023473755"
|
|
"58b938c2e3ca4c2ce48942da97f9e45797f2c074ac6004734e93784a48af6160");
|
|
|
|
std::vector<uint8_t> decrypt_buffer;
|
|
size_t encrypt_length = data.encrypt_data.size();
|
|
decrypt_buffer.resize(encrypt_length);
|
|
|
|
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_,
|
|
data.is_encrypted,
|
|
data.key_id,
|
|
&data.encrypt_data.front(),
|
|
encrypt_length,
|
|
data.iv,
|
|
data.block_offset,
|
|
&decrypt_buffer.front()));
|
|
|
|
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
|
|
decrypt_buffer.begin()));
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, SwitchKeyDecryptionTest) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
uint8_t data_blocks = 2;
|
|
DecryptionData data[data_blocks];
|
|
|
|
// block 0, key 1, encrypted, 256b
|
|
data[0].is_encrypted = true;
|
|
data[0].key_id = wvcdm::a2bs_hex("E02562E04CD55351B14B3D748D36ED8E");
|
|
data[0].encrypt_data = wvcdm::a2b_hex(
|
|
"3b2cbde084973539329bd5656da22d20396249bf4a18a51c38c4743360cc9fea"
|
|
"a1c78d53de1bd7e14dc5d256fd20a57178a98b83804258c239acd7aa38f2d7d2"
|
|
"eca614965b3d22049e19e236fc1800e60965d8b36415677bf2f843d50a6943c4"
|
|
"683c07c114a32f5e5fbc9939c483c3a1b2ecd3d82b554d649798866191724283"
|
|
"f0ab082eba2da79aaca5c4eaf186f9ee9a0c568f621f705a578f30e4e2ef7b96"
|
|
"5e14cc046ce6dbf272ee5558b098f332333e95fc879dea6c29bf34acdb649650"
|
|
"f08201b9e649960f2493fd7677cc3abf5ae70e5445845c947ba544456b431646"
|
|
"d95a133bff5f57614dda5e4446cd8837901d074149dadf4b775b5b07bb88ca20");
|
|
data[0].iv = wvcdm::a2b_hex("4cca615fc013102892f91efee936639b");
|
|
data[0].block_offset = 0;
|
|
data[0].decrypt_data = wvcdm::a2b_hex(
|
|
"5a36c0b633b58faf22156d78fdfb608e54a8095788b2b0463ef78d030b4abf82"
|
|
"eff34b8d9b7b6352e7d72de991b599662aa475da355033620152e2356ebfadee"
|
|
"06172be9e1058fa177e223b9fdd191380cff53c3ea810c6fd852a1df4967b799"
|
|
"415179a2276ec388ef763bab89605b9c6952c28dc8d6bf86b03fabbb46b392a3"
|
|
"1dad15be602eeeeabb45070b3e25d6bb0217073b1fc44c9fe848594121fd6a91"
|
|
"304d605e21f69615e1b57db18312b6b948725724b74e91d8aea7371e99532469"
|
|
"1b358bdee873f1936b63efe83d190a53c2d21754d302d63ff285174023473755"
|
|
"58b938c2e3ca4c2ce48942da97f9e45797f2c074ac6004734e93784a48af6160");
|
|
|
|
// block 1, key 3, encrypted, 256b
|
|
data[1].is_encrypted = true;
|
|
data[1].key_id = wvcdm::a2bs_hex("0065901A64A25899A5193664ABF9AF62");
|
|
data[1].encrypt_data = wvcdm::a2b_hex(
|
|
"337f294addb4c16d1015fd839e80314472432eda503bd0529422318bec7d2b34"
|
|
"2b28d24b2c0bf999fd31711901a2b90e03373cb9553ffd4b2e6e655b80a39fe8"
|
|
"61718220948f0031a37fe277f943409d09c83ff1c19fe8d601f5b4d139821750"
|
|
"47170006db5f38cb84706a9beeaa455fca3b17d8de90c143eb36aaaac3f4670a"
|
|
"7194064f4d59996c95992a3e6a848d4da8adddae3ad03c8d28110fda3e5c1d0a"
|
|
"35d175c816481275a02d2da96c7fc313864ae076f03887309cdf00ca856bad28"
|
|
"2146141964b7f7972e9b253b1fbed6d74ffedcfc51bb91fa78a602479b0b757f"
|
|
"53a16cca15c381a4eab3034ee38e12280982d575fe3de23dd65cf8ba240daa88");
|
|
data[1].iv = wvcdm::a2b_hex("6d4ee851e563b951119cd33c52aadbf5");
|
|
data[1].block_offset = 0;
|
|
data[1].decrypt_data = wvcdm::a2b_hex(
|
|
"c397c1c9bc6782cd859e92f7158e3ff2a54ee984869582b942b400c22ebb6843"
|
|
"7c50f999f73831fa12040f6aab607f57280189ff1db1ab1d0046ffaa55ce1790"
|
|
"3baf0f9c983351b2ff15cc4f61f0f8db6922804e74a207e1e5baaeca67b427c7"
|
|
"2dd7883ee8232041a9c4e56ccfb8bdc3016602c73fa8944e734ee34c41cf1a17"
|
|
"b009b404fd924d23dfee1f494b5e374c9e87c2910de36826044bff89939a70d2"
|
|
"47ff1a8a0baa7643026b8d9442fda69dde6802816ddd4b6e3b18f0a95e788d6d"
|
|
"166ed7435ef663ef019b4438d3e203734eb95d68758e028f29cd623f35cde4bd"
|
|
"edfea33ade378a92a356020bcf3fbba01c9ab16ad448ce6ebe708f768c6676a7");
|
|
std::vector<uint8_t> decrypt_buffer;
|
|
|
|
for (int i = 0; i < data_blocks; ++i) {
|
|
size_t encrypt_length = data[i].encrypt_data.size();
|
|
decrypt_buffer.resize(encrypt_length);
|
|
|
|
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_,
|
|
data[i].is_encrypted,
|
|
data[i].key_id,
|
|
&data[i].encrypt_data.front(),
|
|
encrypt_length,
|
|
data[i].iv,
|
|
data[i].block_offset,
|
|
&decrypt_buffer.front()));
|
|
|
|
EXPECT_TRUE(std::equal(data[i].decrypt_data.begin(),
|
|
data[i].decrypt_data.end(),
|
|
decrypt_buffer.begin()));
|
|
}
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, PartialBlockDecryptionTest) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
// key 3, encrypted, 125b, offset 0
|
|
DecryptionData data;
|
|
data.is_encrypted = true;
|
|
data.key_id = wvcdm::a2bs_hex("0065901A64A25899A5193664ABF9AF62");
|
|
data.encrypt_data = wvcdm::a2b_hex(
|
|
"337f294addb4c16d1015fd839e80314472432eda503bd0529422318bec7d2b34"
|
|
"2b28d24b2c0bf999fd31711901a2b90e03373cb9553ffd4b2e6e655b80a39fe8"
|
|
"61718220948f0031a37fe277f943409d09c83ff1c19fe8d601f5b4d139821750"
|
|
"47170006db5f38cb84706a9beeaa455fca3b17d8de90c143eb36aaaac3");
|
|
data.iv = wvcdm::a2b_hex("6d4ee851e563b951119cd33c52aadbf5");
|
|
data.block_offset = 0;
|
|
data.decrypt_data = wvcdm::a2b_hex(
|
|
"c397c1c9bc6782cd859e92f7158e3ff2a54ee984869582b942b400c22ebb6843"
|
|
"7c50f999f73831fa12040f6aab607f57280189ff1db1ab1d0046ffaa55ce1790"
|
|
"3baf0f9c983351b2ff15cc4f61f0f8db6922804e74a207e1e5baaeca67b427c7"
|
|
"2dd7883ee8232041a9c4e56ccfb8bdc3016602c73fa8944e734ee34c41");
|
|
|
|
std::vector<uint8_t> decrypt_buffer;
|
|
size_t encrypt_length = data.encrypt_data.size();
|
|
decrypt_buffer.resize(encrypt_length);
|
|
|
|
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_,
|
|
data.is_encrypted,
|
|
data.key_id,
|
|
&data.encrypt_data.front(),
|
|
encrypt_length,
|
|
data.iv,
|
|
data.block_offset,
|
|
&decrypt_buffer.front()));
|
|
|
|
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
|
|
decrypt_buffer.begin()));
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, PartialBlockWithOffsetDecryptionTest) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
// key 3, encrypted, 123b, offset 5
|
|
DecryptionData data;
|
|
data.is_encrypted = true;
|
|
data.key_id = wvcdm::a2bs_hex("0065901A64A25899A5193664ABF9AF62");
|
|
data.encrypt_data = wvcdm::a2b_hex(
|
|
"97f39b919ba56f3c3a51ecdcd7318bc130f054320c74db3990f925"
|
|
"054734c03ec79ee0da68938dc4f8c2d91e46ec2342ef24f9328294a9475f7ead"
|
|
"8ad3e71db62d6328e826e4ab375f4796aa2bc8b9266551e3007fb3c253780293"
|
|
"31fbc32ed29afcb9e7152cf072712c5a22c6b52d60e381eb53eeb58d36528746");
|
|
data.iv = wvcdm::a2b_hex("43ba341482212c70f79d81c0f4faef8a");
|
|
data.block_offset = 5;
|
|
data.decrypt_data = wvcdm::a2b_hex(
|
|
"d36911b44f470ff05d152a7bc69ea6b68aa812cd3676964acb4597"
|
|
"b518fe4b7ec0fe44469b1e4f8806922af9ac998d3e23349cea0e68f833564c15"
|
|
"e49584f94ef16b7ab6cd2d0b152430f1fb4d7644a0f591980388ac02012d3d42"
|
|
"73d6c9604517b1a622b66b8f4e8414e40b00351cc9859061bde810190c7b5df8");
|
|
|
|
std::vector<uint8_t> decrypt_buffer;
|
|
size_t encrypt_length = data.encrypt_data.size();
|
|
decrypt_buffer.resize(encrypt_length);
|
|
|
|
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_,
|
|
data.is_encrypted,
|
|
data.key_id,
|
|
&data.encrypt_data.front(),
|
|
encrypt_length,
|
|
data.iv,
|
|
data.block_offset,
|
|
&decrypt_buffer.front()));
|
|
|
|
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
|
|
decrypt_buffer.begin()));
|
|
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
|
|
// TODO(rfrias, edwinwong): pending L1 OEMCrypto due to key block handling
|
|
/*
|
|
TEST_F(WvCdmRequestLicenseTest, KeyControlBlockDecryptionTest) {
|
|
decryptor_.OpenSession(g_key_system, &session_id_);
|
|
GenerateKeyRequest(g_key_system, g_key_id);
|
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
|
|
|
DecryptionData data;
|
|
|
|
// block 4, key 2, encrypted
|
|
data.is_encrypted = true;
|
|
data.key_id = wvcdm::a2bs_hex("0915007CAA9B5931B76A3A85F046523E");
|
|
data.encrypt_data = wvcdm::a2b_hex(
|
|
"6758ac1c6ccf5d08479e3bfc62bbc0fd154aff4415aa7ed53d89e3983248d117"
|
|
"ab5137ae7cedd9f9d7321d4cf35a7013237afbcc2d893d1d928efa94e9f7e2ed"
|
|
"1855463cf75ff07ecc0246b90d0734f42d98aeea6a0a6d2618a8339bd0aca368"
|
|
"4fb4a4670c0385e5bd5de9e2d8b9226851b8f8955adfbab968793b46fd152f5e"
|
|
"e608467bb2695836f8f76c32731f5e208176d05e4b07020d58f6282c477f3840"
|
|
"b8079c02e8bd1d03191d190cc505ddfbb2e9bacc794534c91fe409d62f5389b9"
|
|
"35ed66134bd30f09f8da9dbfe6b8cf53d13cae34dae6e89109216e3a02233d5c"
|
|
"2f66aef74313aae4a99b654b485b5cc207b2dc8d44a8b99a4dc196a9820eccef");
|
|
data.iv = wvcdm::a2b_hex("c8f2d133ec357fe727cd233b3bfa755f");
|
|
data.block_offset = 0;
|
|
data.decrypt_data = wvcdm::a2b_hex(
|
|
"34bab89185f1be990dfc454410c7c9093d008bc783908838b02a65b26db28759"
|
|
"dca9dc5f117b3c8c3898358722d1b4c490e5a5d168ba0f9f8a3d4371b8fd1057"
|
|
"2d6dd65f3f9d1850de8d76dc71bd6dc6c23da4e1223fcc3e47162033a6f82890"
|
|
"e2bd6e9d6ddbe453830afc89064ed18078c786f8f746fcbafd88e83e7160cce5"
|
|
"62fa7a7d699ef8421bda020d242ae4f61a786213b707c3b17b83d77510f9a07e"
|
|
"d9d7e47d8f8fa2aff86eb26d61ddf384a27513e3facf6b1f5fe6c0d063b8856c"
|
|
"c486d930393ea79ba73ba293eda39059e2ce9ee7bd5d31ab11f35e55dc35dfe0"
|
|
"ea5e2ec684014852add6e29ce7d88a1595641ae4c0dd10155526b5a87560ec9d");
|
|
|
|
std::vector<uint8_t> decrypt_buffer;
|
|
size_t encrypt_length = data[i].encrypt_data.size();
|
|
decrypt_buffer.resize(encrypt_length);
|
|
|
|
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_,
|
|
data.is_encrypted,
|
|
data.key_id,
|
|
&data.encrypt_data.front(),
|
|
encrypt_length,
|
|
data.iv,
|
|
data.block_offset,
|
|
&decrypt_buffer.front()));
|
|
|
|
EXPECT_TRUE(std::equal(data.decrypt_data.begin(),
|
|
data.decrypt_data.end(),
|
|
decrypt_buffer.begin()));
|
|
}
|
|
decryptor_.CloseSession(session_id_);
|
|
}
|
|
*/
|
|
} // namespace wvcdm
|
|
|
|
int main(int argc, char **argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
|
|
wvcdm::ConfigTestEnv config;
|
|
g_client_auth.assign(config.client_auth());
|
|
g_key_system.assign(config.key_system());
|
|
g_wrong_key_id.assign(config.wrong_key_id());
|
|
|
|
// The following variables are configurable through command line options.
|
|
g_license_server.assign(config.license_server());
|
|
g_key_id.assign(config.key_id());
|
|
g_port.assign(config.port());
|
|
std::string license_server(g_license_server);
|
|
|
|
int show_usage = 0;
|
|
static const struct option long_options[] = {
|
|
{ "use_full_path", no_argument, &g_use_full_path, 0 },
|
|
{ "keyid", required_argument, NULL, 'k' },
|
|
{ "port", required_argument, NULL, 'p' },
|
|
{ "server", required_argument, NULL, 's' },
|
|
{ NULL, 0, NULL, '\0' }
|
|
};
|
|
|
|
int option_index = 0;
|
|
int opt = 0;
|
|
while ((opt = getopt_long(argc, argv, "k:p:s:u", long_options, &option_index)) != -1) {
|
|
switch (opt) {
|
|
case 'k': {
|
|
g_key_id.clear();
|
|
g_key_id.assign(optarg);
|
|
break;
|
|
}
|
|
case 'p': {
|
|
g_port.clear();
|
|
g_port.assign(optarg);
|
|
break;
|
|
}
|
|
case 's': {
|
|
g_license_server.clear();
|
|
g_license_server.assign(optarg);
|
|
break;
|
|
}
|
|
case 'u': {
|
|
g_use_full_path = 1;
|
|
break;
|
|
}
|
|
case '?': {
|
|
show_usage = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (show_usage) {
|
|
std::cout << std::endl;
|
|
std::cout << "usage: " << argv[0] << " [options]" << std::endl << std::endl;
|
|
std::cout << " enclose multiple arguments in '' when using adb shell" << std::endl;
|
|
std::cout << " e.g. adb shell '" << argv[0] << " --server=\"url\"'" << std::endl << std::endl;
|
|
|
|
std::cout << std::setw(30) << std::left << " --port=<connection port>";
|
|
std::cout << "specifies the port number, in decimal format" << std::endl;
|
|
std::cout << std::setw(30) << std::left << " ";
|
|
std::cout << "default: " << g_port << std::endl;
|
|
|
|
std::cout << std::setw(30) << std::left << " --server=<server_url>";
|
|
std::cout << "configure the license server url, please include http[s] in the url" << std::endl;
|
|
std::cout << std::setw(30) << std::left << " ";
|
|
std::cout << "default: " << license_server << std::endl;
|
|
|
|
std::cout << std::setw(30) << std::left << " --keyid=<key_id>";
|
|
std::cout << "configure the key id or pssh, in hex format" << std::endl;
|
|
std::cout << std::setw(30) << std::left << " default keyid:";
|
|
std::cout << g_key_id << std::endl;
|
|
|
|
std::cout << std::setw(30) << std::left << " --use_full_path";
|
|
std::cout << "specify server url is not a proxy server" << std::endl;
|
|
std::cout << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
std::cout << std::endl;
|
|
std::cout << "Server: " << g_license_server << std::endl;
|
|
std::cout << "Port: " << g_port << std::endl;
|
|
std::cout << "KeyID: " << g_key_id << std::endl << std::endl;
|
|
|
|
g_key_id = wvcdm::a2bs_hex(g_key_id);
|
|
config.set_license_server(g_license_server);
|
|
config.set_port(g_port);
|
|
config.set_key_id(g_key_id);
|
|
|
|
return RUN_ALL_TESTS();
|
|
}
|