Merges to android Pi release (part 3)
These are a set of CLs merged from the wv cdm repo to the android repo. * Add CDM status return for decrypt blocked by HDCP. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/28062 ] New status code is kKeyUsageBlockedByPolicy. It is returned by the decrypt() call instead of kDecryptError or kNoKey. Also shuffled the CDM status returns to define the EME-aligned codes first, and added comments to highlight the differences in handling. BUG: 37540672 * Change division and mod ops to relocatables Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/28600 ] This is similar to I2dad1028acf295288cd10817a2bcff2513c053c9. We should be using the relocatable functions instead of the native division and mod operations. * Cleanup Encrypted ClientID in provisioning request Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/28083 ] b/36897239 Staging server does not support it (or the client is not constructing it properly). Leave it disabled pending investigation. * Certificate Provisioning fixes. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/28066 ] Partial fix for BUG: 37482676 Partial fix for BUG: 37481392 Update service certificates, get rid of DEV/QA root certificate. Provisioning request and response are base64 (web-safe) encoded. Response is optionally JSON-wrapped. Change ConfigTestEnv; clearer comments and a closer match to reality. BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: I79d3c4bf1124e5e0d3e4d40baead65a8266ea874
This commit is contained in:
@@ -38,24 +38,26 @@ KeyId g_key_id_unwrapped;
|
||||
CdmKeySystem g_key_system;
|
||||
std::string g_license_server;
|
||||
std::string g_provisioning_server;
|
||||
std::string g_service_certificate;
|
||||
std::string g_provisioning_service_certificate;
|
||||
std::string g_license_service_certificate;
|
||||
KeyId g_wrong_key_id;
|
||||
|
||||
const std::string kCencMimeType = "video/mp4";
|
||||
const std::string kWebmMimeType = "video/webm";
|
||||
|
||||
static void CommonSetup(bool use_qa) {
|
||||
static void CommonSetup(ServerConfigurationId which) {
|
||||
|
||||
// NOTE: Select QA/Test server config vs. UAT server config
|
||||
ConfigTestEnv config((use_qa) ? kContentProtectionTestQAServer :
|
||||
kContentProtectionUatServer);
|
||||
// NOTE: Select configuration
|
||||
ConfigTestEnv config(which);
|
||||
|
||||
g_client_auth.assign(config.client_auth());
|
||||
g_key_system.assign(config.key_system());
|
||||
g_wrong_key_id.assign(config.wrong_key_id());
|
||||
g_license_server.assign(config.license_server());
|
||||
g_key_id_pssh.assign(a2bs_hex(config.key_id()));
|
||||
g_service_certificate.assign(config.service_certificate());
|
||||
g_provisioning_service_certificate.assign(
|
||||
config.provisioning_service_certificate());
|
||||
g_license_service_certificate.assign(config.license_service_certificate());
|
||||
g_provisioning_server.assign(config.provisioning_server());
|
||||
|
||||
// Extract the key ID from the PSSH box.
|
||||
@@ -63,6 +65,45 @@ static void CommonSetup(bool use_qa) {
|
||||
g_key_id_unwrapped = extractor.data();
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the portion of the server's response message that is between
|
||||
* the strings jason_start_substr and json_end_substr. Returns the string
|
||||
* through *result. If the start substring match fails, assume the entire
|
||||
* string represents a serialized protobuf mesaage and return true with
|
||||
* the entire string. If the end_substring match fails, return false with
|
||||
* an empty *result.
|
||||
*/
|
||||
bool ExtractSignedMessage(const std::string& response,
|
||||
const std::string& json_start_substr,
|
||||
const std::string& json_end_substr,
|
||||
std::string* result) {
|
||||
std::string response_string;
|
||||
size_t start = response.find(json_start_substr);
|
||||
|
||||
if (start == response.npos) {
|
||||
// Assume serialized protobuf message.
|
||||
result->assign(response);
|
||||
} else {
|
||||
// Assume JSON-wrapped protobuf.
|
||||
size_t end = response.find(json_end_substr,
|
||||
start + json_start_substr.length());
|
||||
if (end == response.npos) {
|
||||
LOGE("ExtractSignedMessage cannot locate end substring");
|
||||
result->clear();
|
||||
return false;
|
||||
}
|
||||
size_t result_string_size = end - start - json_start_substr.length();
|
||||
result->assign(response, start + json_start_substr.length(),
|
||||
result_string_size);
|
||||
}
|
||||
|
||||
if (result->empty()) {
|
||||
LOGE("ExtractSignedMessage: Response message is empty");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class WvCdmEnginePreProvTest : public testing::Test {
|
||||
@@ -72,15 +113,6 @@ class WvCdmEnginePreProvTest : public testing::Test {
|
||||
|
||||
virtual ~WvCdmEnginePreProvTest() {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
// NOTE: Select QA/Test server config vs. UAT server config
|
||||
#if defined(QA_TEST_SERVER)
|
||||
CommonSetup(true);
|
||||
#else
|
||||
CommonSetup(false);
|
||||
#endif // !defined(QA_TEST_SERVER)
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
CdmResponseType status =
|
||||
cdm_engine_.OpenSession(g_key_system, NULL, NULL, &session_id_);
|
||||
@@ -97,24 +129,11 @@ class WvCdmEnginePreProvTest : public testing::Test {
|
||||
|
||||
protected:
|
||||
|
||||
bool IsBase64Encoded(const std::string& message) {
|
||||
for (size_t i = 0; i < message.size(); ++i) {
|
||||
uint8_t ch = message[i];
|
||||
if (ch >= 'a' && ch <= 'z') continue;
|
||||
if (ch >= 'A' && ch <= 'Z') continue;
|
||||
if (ch >= '0' && ch <= '9') continue;
|
||||
if (ch == '-' || ch == '_' || ch == '=' || ch == '.' || ch == '/') {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Trade request for response via the license server.
|
||||
bool LicenseServerRequestResponse(const std::string& request,
|
||||
std::string* response) {
|
||||
LOGV("server url: %s", g_license_server.c_str());
|
||||
LOGV("LicenseServerRequestResponse: server url: %s",
|
||||
g_license_server.c_str());
|
||||
UrlRequest url_request(g_license_server + g_client_auth);
|
||||
url_request.PostRequest(request);
|
||||
|
||||
@@ -123,29 +142,67 @@ class WvCdmEnginePreProvTest : public testing::Test {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV("http_resp:\n%s\n", http_response.c_str());
|
||||
LOGV("http_response:\n%s\n", http_response.c_str());
|
||||
|
||||
// Separate message from HTTP headers.
|
||||
LicenseRequest license_request;
|
||||
std::string response_message;
|
||||
license_request.GetDrmMessage(http_response, response_message);
|
||||
license_request.GetDrmMessage(http_response, *response);
|
||||
|
||||
LOGV("resp: size=%u, string:\n%s\n", response_message.size(),
|
||||
Base64SafeEncode(
|
||||
std::vector<uint8_t>(response_message.begin(),
|
||||
response_message.end())).c_str());
|
||||
|
||||
// Response should be base64 encoded. If it is not,
|
||||
// fix it now.
|
||||
if (!IsBase64Encoded(response_message)) {
|
||||
std::vector<uint8_t> response_vector(response_message.begin(),
|
||||
response_message.end());
|
||||
response_message = Base64SafeEncode(response_vector);
|
||||
}
|
||||
response->swap(response_message);
|
||||
LOGV("response: size=%u, string:\n%s\n", response->size(),
|
||||
Base64SafeEncode(std::vector<uint8_t>(response->begin(),
|
||||
response->end())).c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Provision() {
|
||||
LOGV("WvCdmEnginePreProvTest::Provision: url=%s",
|
||||
g_provisioning_server.c_str());
|
||||
CdmProvisioningRequest prov_request;
|
||||
std::string provisioning_server_url;
|
||||
CdmCertificateType cert_type = kCertificateWidevine;
|
||||
std::string cert_authority;
|
||||
std::string cert, wrapped_key;
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine_.SetServiceCertificate(
|
||||
g_provisioning_service_certificate));
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine_.GetProvisioningRequest(
|
||||
cert_type, cert_authority, &prov_request,
|
||||
&provisioning_server_url));
|
||||
|
||||
LOGV("WvCdmEnginePreProvTest::Provision: req=%s", prov_request.c_str());
|
||||
|
||||
// Ignore URL provided by CdmEngine. Use ours, as configured
|
||||
// for test vs. production server.
|
||||
provisioning_server_url.assign(g_provisioning_server);
|
||||
UrlRequest url_request(provisioning_server_url);
|
||||
EXPECT_TRUE(url_request.is_connected());
|
||||
url_request.PostCertRequestInQueryString(prov_request);
|
||||
std::string http_message;
|
||||
bool ok = url_request.GetResponse(&http_message);
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
LOGV("WvCdmEnginePreProvTest::Provision: http_message: \n%s\n",
|
||||
http_message.c_str());
|
||||
|
||||
// extract provisioning response from received message
|
||||
// Extracts signed response from JSON string, result is serialized protobuf.
|
||||
const std::string kMessageStart = "\"signedResponse\": \"";
|
||||
const std::string kMessageEnd = "\"";
|
||||
std::string protobuf_response;
|
||||
EXPECT_TRUE (ExtractSignedMessage(http_message, kMessageStart, kMessageEnd,
|
||||
&protobuf_response)) <<
|
||||
"Failed to extract signed serialized response from JSON response";
|
||||
|
||||
LOGV("WvCdmEnginePreProvTest::Provision: extracted response "
|
||||
"message: \n%s\n", protobuf_response.c_str());
|
||||
|
||||
ASSERT_EQ(NO_ERROR,
|
||||
cdm_engine_.HandleProvisioningResponse(protobuf_response,
|
||||
&cert, &wrapped_key));
|
||||
|
||||
ASSERT_EQ(NO_ERROR,
|
||||
cdm_engine_.SetServiceCertificate(g_license_service_certificate));
|
||||
}
|
||||
|
||||
FileSystem file_system_;
|
||||
CdmEngine cdm_engine_;
|
||||
bool session_opened_;
|
||||
@@ -153,10 +210,75 @@ class WvCdmEnginePreProvTest : public testing::Test {
|
||||
std::string session_id_;
|
||||
};
|
||||
|
||||
class WvCdmEnginePreProvTestStaging : public WvCdmEnginePreProvTest {
|
||||
public:
|
||||
WvCdmEnginePreProvTestStaging() {}
|
||||
|
||||
virtual ~WvCdmEnginePreProvTestStaging() {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
// NOTE: Select server configuration
|
||||
CommonSetup(kContentProtectionStagingLicense);
|
||||
}
|
||||
};
|
||||
|
||||
class WvCdmEnginePreProvTestProd : public WvCdmEnginePreProvTest {
|
||||
public:
|
||||
WvCdmEnginePreProvTestProd() {}
|
||||
|
||||
virtual ~WvCdmEnginePreProvTestProd() {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
// NOTE: Select server configuration
|
||||
CommonSetup(kContentProtectionProdLicense);
|
||||
}
|
||||
};
|
||||
|
||||
class WvCdmEnginePreProvTestUat : public WvCdmEnginePreProvTest {
|
||||
public:
|
||||
WvCdmEnginePreProvTestUat() {}
|
||||
|
||||
virtual ~WvCdmEnginePreProvTestUat() {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
// NOTE: Select server configuration
|
||||
CommonSetup(kContentProtectionUatLicense);
|
||||
}
|
||||
};
|
||||
|
||||
class WvCdmEnginePreProvTestStagingProv30 : public WvCdmEnginePreProvTest {
|
||||
public:
|
||||
WvCdmEnginePreProvTestStagingProv30() {}
|
||||
|
||||
virtual ~WvCdmEnginePreProvTestStagingProv30() {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
// NOTE: Select server configuration
|
||||
CommonSetup(kContentProtectionStagingPlusProv30);
|
||||
}
|
||||
};
|
||||
|
||||
class WvCdmEnginePreProvTestUatProv30 : public WvCdmEnginePreProvTest {
|
||||
public:
|
||||
WvCdmEnginePreProvTestUatProv30() {}
|
||||
|
||||
virtual ~WvCdmEnginePreProvTestUatProv30() {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
// NOTE: Select server configuration
|
||||
CommonSetup(kContentProtectionUatPlusProv30);
|
||||
}
|
||||
};
|
||||
|
||||
class WvCdmEngineTest : public WvCdmEnginePreProvTest {
|
||||
public:
|
||||
WvCdmEngineTest() {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
// NOTE: Select server configuration
|
||||
CommonSetup(kContentProtectionStagingLicense);
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
CdmResponseType status =
|
||||
cdm_engine_.OpenSession(g_key_system, NULL, NULL, &session_id_);
|
||||
@@ -170,43 +292,6 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest {
|
||||
}
|
||||
|
||||
protected:
|
||||
void Provision() {
|
||||
CdmProvisioningRequest prov_request;
|
||||
std::string provisioning_server_url;
|
||||
CdmCertificateType cert_type = kCertificateWidevine;
|
||||
std::string cert_authority;
|
||||
std::string cert, wrapped_key;
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine_.SetServiceCertificate(
|
||||
g_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);
|
||||
if (result == CERT_PROVISIONING_NONCE_GENERATION_ERROR) {
|
||||
LOGW("Woops. Nonce problem. Try again?");
|
||||
sleep(1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(NO_ERROR, result);
|
||||
// Ignore URL provided by CdmEngine. Use ours, as configured
|
||||
// for test vs. production server.
|
||||
provisioning_server_url.assign(g_provisioning_server);
|
||||
UrlRequest url_request(provisioning_server_url);
|
||||
EXPECT_TRUE(url_request.is_connected());
|
||||
url_request.PostCertRequestInQueryString(prov_request);
|
||||
std::string message;
|
||||
bool ok = url_request.GetResponse(&message);
|
||||
EXPECT_TRUE(ok);
|
||||
// One of many reasons a device might fail to provision is that the server
|
||||
// rejects its keybox. In that case, we usually see an error of
|
||||
// CERT_PROVISIONING_RESPONSE_ERROR_1. The error response may help
|
||||
// somebody look through the server logs for more clues.
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine_.HandleProvisioningResponse(message, &cert,
|
||||
&wrapped_key))
|
||||
<< "Error response: " << message;
|
||||
}
|
||||
|
||||
void GenerateKeyRequest(const std::string& key_id,
|
||||
const std::string& init_data_type_string) {
|
||||
@@ -269,6 +354,9 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest {
|
||||
const std::string& client_auth,
|
||||
bool expect_success) {
|
||||
// Use secure connection and chunk transfer coding.
|
||||
|
||||
LOGV("GetKeyRequestResponse: server_url: %s", server_url.c_str());
|
||||
|
||||
UrlRequest url_request(server_url + client_auth);
|
||||
if (!url_request.is_connected()) {
|
||||
return "";
|
||||
@@ -315,19 +403,19 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest {
|
||||
};
|
||||
|
||||
// Test that service certificate is initially absent.
|
||||
TEST_F(WvCdmEnginePreProvTest, ServiceCertificateInitialNoneTest) {
|
||||
TEST_F(WvCdmEnginePreProvTestStaging, ServiceCertificateInitialNoneTest) {
|
||||
ASSERT_FALSE(cdm_engine_.HasServiceCertificate());
|
||||
};
|
||||
|
||||
// Test that service certificate can be properly installed.
|
||||
TEST_F(WvCdmEnginePreProvTest, ServiceCertificateGoodTest) {
|
||||
ASSERT_EQ(cdm_engine_.SetServiceCertificate(g_service_certificate),
|
||||
TEST_F(WvCdmEnginePreProvTestStaging, ServiceCertificateGoodTest) {
|
||||
ASSERT_EQ(cdm_engine_.SetServiceCertificate(g_license_service_certificate),
|
||||
NO_ERROR);
|
||||
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
|
||||
};
|
||||
|
||||
// Test that service certificate can be retrieved from the license server.
|
||||
TEST_F(WvCdmEnginePreProvTest, ServiceCertificateRequestResponse) {
|
||||
TEST_F(WvCdmEnginePreProvTestStaging, ServiceCertificateRequestResponse) {
|
||||
CdmKeyMessage request;
|
||||
std::string certificate;
|
||||
|
||||
@@ -335,65 +423,110 @@ TEST_F(WvCdmEnginePreProvTest, ServiceCertificateRequestResponse) {
|
||||
ASSERT_FALSE(cdm_engine_.HasServiceCertificate());
|
||||
|
||||
// Generate request.
|
||||
// The request will be a base64 encode of a serialized protobuf message.
|
||||
// The request will be a serialized protobuf message.
|
||||
ASSERT_TRUE(cdm_engine_.GetServiceCertificateRequest(&request));
|
||||
|
||||
LOGV("ret'd request message:\"%s\"", request.c_str());
|
||||
|
||||
std::string response;
|
||||
ASSERT_TRUE(LicenseServerRequestResponse(request, &response));
|
||||
|
||||
// Extract the service certificate
|
||||
if (cdm_engine_.ParseServiceCertificateResponse(response, &certificate) ==
|
||||
NO_ERROR) {
|
||||
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
|
||||
LOGV("ret'd cert:\"%s\"", b2a_hex(certificate).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Message did not parse. Possibly it is because of base64 encoding
|
||||
// of the request. Try again with binary (base64 decoded) message.
|
||||
|
||||
LOGE("Base64 encoded request failed - RETRY with binary request");
|
||||
|
||||
while (request.size() % 4 != 0) {
|
||||
request = request + "="; // add padding if necessary
|
||||
}
|
||||
std::vector<uint8_t> binary_vector = Base64SafeDecode(request);
|
||||
std::string binary_request(binary_vector.begin(), binary_vector.end());
|
||||
LOGV("raw_string=%s", b2a_hex(binary_request).c_str());
|
||||
|
||||
ASSERT_TRUE(LicenseServerRequestResponse(binary_request, &response));
|
||||
|
||||
ASSERT_EQ(cdm_engine_.ParseServiceCertificateResponse(response, &certificate),
|
||||
NO_ERROR);
|
||||
|
||||
LOGV("ret'd cert:\"%s\"", b2a_hex(certificate).c_str());
|
||||
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
|
||||
LOGV("ret'd service certificate:\n%s\n", b2a_hex(certificate).c_str());
|
||||
};
|
||||
|
||||
// Test that service certificate can be retrieved from the license server.
|
||||
TEST_F(WvCdmEnginePreProvTestUat, ServiceCertificateRequestResponse) {
|
||||
CdmKeyMessage request;
|
||||
std::string certificate;
|
||||
|
||||
// Initial condition - no service certificate.
|
||||
ASSERT_FALSE(cdm_engine_.HasServiceCertificate());
|
||||
|
||||
// Generate request.
|
||||
// The request will be a serialized protobuf message.
|
||||
ASSERT_TRUE(cdm_engine_.GetServiceCertificateRequest(&request));
|
||||
|
||||
std::string response;
|
||||
ASSERT_TRUE(LicenseServerRequestResponse(request, &response));
|
||||
|
||||
// Extract the service certificate
|
||||
ASSERT_EQ(cdm_engine_.ParseServiceCertificateResponse(response, &certificate),
|
||||
NO_ERROR);
|
||||
|
||||
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
|
||||
LOGV("ret'd service certificate:\n%s\n", b2a_hex(certificate).c_str());
|
||||
};
|
||||
|
||||
// Test that service certificate can be retrieved from the license server.
|
||||
TEST_F(WvCdmEnginePreProvTestProd, ServiceCertificateRequestResponse) {
|
||||
CdmKeyMessage request;
|
||||
std::string certificate;
|
||||
|
||||
// Initial condition - no service certificate.
|
||||
ASSERT_FALSE(cdm_engine_.HasServiceCertificate());
|
||||
|
||||
// Generate request.
|
||||
// The request will be a serialized protobuf message.
|
||||
ASSERT_TRUE(cdm_engine_.GetServiceCertificateRequest(&request));
|
||||
|
||||
std::string response;
|
||||
ASSERT_TRUE(LicenseServerRequestResponse(request, &response));
|
||||
|
||||
// Extract the service certificate
|
||||
ASSERT_EQ(cdm_engine_.ParseServiceCertificateResponse(response, &certificate),
|
||||
NO_ERROR);
|
||||
|
||||
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
|
||||
LOGV("ret'd service certificate:\n%s\n", b2a_hex(certificate).c_str());
|
||||
};
|
||||
|
||||
// Test that empty service certificate fails.
|
||||
TEST_F(WvCdmEnginePreProvTest, ServiceCertificateEmptyFailTest) {
|
||||
TEST_F(WvCdmEnginePreProvTestStaging, ServiceCertificateEmptyFailTest) {
|
||||
std::string empty_cert;
|
||||
ASSERT_EQ(cdm_engine_.SetServiceCertificate(g_service_certificate),
|
||||
ASSERT_EQ(cdm_engine_.SetServiceCertificate(g_license_service_certificate),
|
||||
NO_ERROR);
|
||||
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
|
||||
};
|
||||
|
||||
// Test that provisioning works, even if device is already provisioned.
|
||||
TEST_F(WvCdmEngineTest, DISABLED_Provisioning30Test) {
|
||||
TEST_F(WvCdmEnginePreProvTestStaging, DISABLED_ProvisioningTest) {
|
||||
uint32_t nonce = 0;
|
||||
uint8_t buffer[1];
|
||||
size_t size = 0;
|
||||
|
||||
int result = OEMCrypto_RewrapDeviceRSAKey(
|
||||
0, buffer, 0, buffer, 0, &nonce, buffer, 0, buffer, buffer, &size);
|
||||
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
int result30 = OEMCrypto_RewrapDeviceRSAKey30(
|
||||
0, &nonce, buffer, 0, buffer, 0, buffer, buffer, &size);
|
||||
int method = OEMCrypto_GetProvisioningMethod(kLevelDefault);
|
||||
|
||||
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED &&
|
||||
result30 == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
LOGW("WARNING: Skipping ProvisioningTest because the device does not "
|
||||
"support provisioning. If you are using a baked-in certificate, this "
|
||||
"is expected. Otherwise, something is wrong.");
|
||||
return;
|
||||
"support provisioning. If you are using a baked-in certificate, "
|
||||
"this is expected. Otherwise, something is wrong.");
|
||||
ASSERT_EQ(method, OEMCrypto_DrmCertificate);
|
||||
} else {
|
||||
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
ASSERT_EQ(method, OEMCrypto_OEMCertificate);
|
||||
} else {
|
||||
ASSERT_EQ(method, OEMCrypto_Keybox);
|
||||
}
|
||||
}
|
||||
|
||||
Provision();
|
||||
}
|
||||
|
||||
TEST_F(WvCdmEnginePreProvTestStagingProv30, ProvisioningTest) {
|
||||
Provision();
|
||||
}
|
||||
|
||||
// Test that provisioning works, even if device is already provisioned.
|
||||
TEST_F(WvCdmEngineTest, DISABLED_ProvisioningTest) {
|
||||
|
||||
Provision();
|
||||
}
|
||||
|
||||
@@ -403,7 +536,7 @@ TEST_F(WvCdmEngineTest, BaseIsoBmffMessageTest) {
|
||||
}
|
||||
|
||||
// TODO(juce): Set up with correct test data.
|
||||
TEST_F(WvCdmEngineTest, BaseWebmMessageTest) {
|
||||
TEST_F(WvCdmEngineTest, DISABLED_BaseWebmMessageTest) {
|
||||
GenerateKeyRequest(g_key_id_unwrapped, kWebmMimeType);
|
||||
GetKeyRequestResponse(g_license_server, g_client_auth);
|
||||
}
|
||||
@@ -423,7 +556,7 @@ TEST_F(WvCdmEngineTest, NormalDecryptionIsoBmff) {
|
||||
}
|
||||
|
||||
// TODO(juce): Set up with correct test data.
|
||||
TEST_F(WvCdmEngineTest, NormalDecryptionWebm) {
|
||||
TEST_F(WvCdmEngineTest, DISABLED_NormalDecryptionWebm) {
|
||||
GenerateKeyRequest(g_key_id_unwrapped, kWebmMimeType);
|
||||
VerifyNewKeyResponse(g_license_server, g_client_auth);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
#include "config_test_env.h"
|
||||
#include "string_conversions.h"
|
||||
|
||||
// Holds the data needed to talk to the various provisioning and
|
||||
// license servers.
|
||||
//
|
||||
// Define a series of configurations, and specify the specific
|
||||
// data items needed for that configuration.
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
namespace {
|
||||
@@ -95,18 +101,14 @@ const std::string kUatServiceCertificate =
|
||||
"38540F8A0C227C0011E0F5B38E4E298ED2CB301EB4564965F55C5D79757A"
|
||||
"250A4EB9C84AB3E6539F6B6FDF56899EA29914";
|
||||
|
||||
// QA/Test server (kContentProtectionTestQAServer)
|
||||
//
|
||||
const std::string kQALicenseServerUrl =
|
||||
"https://widevine-proxy-qa.corp.google.com/proxy";
|
||||
|
||||
const std::string kQAProvisioningServerUrl =
|
||||
"http://www-googleapis-test.sandbox.google.com/"
|
||||
"certificateprovisioning/v1/devicecertificates/create";
|
||||
// Content Protection license server (Production) data
|
||||
const std::string kCpProdLicenseServer =
|
||||
"https://widevine-proxy.appspot.com/proxy";
|
||||
|
||||
// Content Protection license server (UAT) data
|
||||
const std::string kCpUatLicenseServer =
|
||||
"http://widevine-proxy.appspot.com/proxy";
|
||||
"https://proxy.uat.widevine.com/proxy";
|
||||
|
||||
const std::string kCpClientAuth = "";
|
||||
const std::string kCpKeyId =
|
||||
"00000042" // blob size
|
||||
@@ -130,7 +132,7 @@ const std::string kCpOfflineKeyId =
|
||||
|
||||
// Content Protection license server (staging) data
|
||||
const std::string kCpStagingLicenseServer =
|
||||
"http://wv-staging-proxy.appspot.com/proxy";
|
||||
"https://proxy.staging.widevine.com/proxy";
|
||||
|
||||
// Google Play license server data
|
||||
const std::string kGpLicenseServer =
|
||||
@@ -181,28 +183,47 @@ const std::string kStagingProvisioningServerUrl =
|
||||
"certificateprovisioning/v1/devicecertificates/create"
|
||||
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
|
||||
|
||||
|
||||
const ConfigTestEnv::LicenseServerConfiguration license_servers[] = {
|
||||
{kGooglePlayServer, kGpLicenseServer, kGpClientAuth, kGpKeyId,
|
||||
kGpOfflineKeyId, "", kStagingProvisioningServerUrl},
|
||||
{kContentProtectionUatServer, kCpUatLicenseServer, kCpClientAuth,
|
||||
kCpKeyId, kCpOfflineKeyId, kProdServiceCertificate,
|
||||
kStagingProvisioningServerUrl},
|
||||
{kContentProtectionStagingServer, kCpStagingLicenseServer,
|
||||
kCpClientAuth, kCpKeyId, kCpOfflineKeyId, kProdServiceCertificate,
|
||||
kStagingProvisioningServerUrl},
|
||||
{kGooglePlayServer, kGpLicenseServer, "", kGpClientAuth, kGpKeyId,
|
||||
kGpOfflineKeyId, kStagingProvisioningServerUrl, ""},
|
||||
|
||||
{kContentProtectionProdLicense, kCpProdLicenseServer,
|
||||
kProdServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
|
||||
kProductionProvisioningServerUrl, kProdServiceCertificate},
|
||||
|
||||
{kContentProtectionUatLicense, kCpUatLicenseServer,
|
||||
kProdServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
|
||||
kProductionProvisioningServerUrl, kProdServiceCertificate},
|
||||
|
||||
{kContentProtectionStagingLicense, kCpStagingLicenseServer,
|
||||
kProdServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
|
||||
kStagingProvisioningServerUrl, kStagingServiceCertificate},
|
||||
|
||||
{kContentProtectionProdPlusProv30, kCpProdLicenseServer,
|
||||
kProdServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
|
||||
kStagingProvisioningServerUrl, kStagingServiceCertificate},
|
||||
|
||||
{kContentProtectionUatPlusProv30, kCpUatLicenseServer,
|
||||
kProdServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
|
||||
kStagingProvisioningServerUrl, kStagingServiceCertificate},
|
||||
|
||||
{kContentProtectionStagingPlusProv30, kCpStagingLicenseServer,
|
||||
kStagingServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
|
||||
kStagingProvisioningServerUrl, kStagingServiceCertificate},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id) { Init(server_id); }
|
||||
ConfigTestEnv::ConfigTestEnv(ServerConfigurationId server_id) {
|
||||
Init(server_id);
|
||||
}
|
||||
|
||||
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming) {
|
||||
ConfigTestEnv::ConfigTestEnv(ServerConfigurationId server_id, bool streaming) {
|
||||
Init(server_id);
|
||||
if (!streaming) key_id_ = license_servers[server_id].offline_key_id;
|
||||
}
|
||||
|
||||
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming,
|
||||
ConfigTestEnv::ConfigTestEnv(ServerConfigurationId server_id, bool streaming,
|
||||
bool renew, bool release) {
|
||||
Init(server_id);
|
||||
if (!streaming) {
|
||||
@@ -220,13 +241,16 @@ ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming,
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigTestEnv::Init(LicenseServerId server_id) {
|
||||
void ConfigTestEnv::Init(ServerConfigurationId server_id) {
|
||||
client_auth_ = license_servers[server_id].client_tag;
|
||||
key_id_ = license_servers[server_id].key_id;
|
||||
key_system_ = kWidevineKeySystem;
|
||||
license_server_ = license_servers[server_id].url;
|
||||
provisioning_server_ = license_servers[server_id].provisioning_server;
|
||||
service_certificate_ = a2bs_hex(license_servers[server_id].service_certificate);
|
||||
license_server_ = license_servers[server_id].license_server_url;
|
||||
provisioning_server_ = license_servers[server_id].provisioning_server_url;
|
||||
license_service_certificate_ =
|
||||
a2bs_hex(license_servers[server_id].license_service_certificate);
|
||||
provisioning_service_certificate_ =
|
||||
a2bs_hex(license_servers[server_id].provisioning_service_certificate);
|
||||
wrong_key_id_ = kWrongKeyId;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,30 +6,50 @@
|
||||
#include <string>
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
// Declare class ConfigTestEnv - holds the configuration settings needed
|
||||
// to talk to the various provisioning and license servers.
|
||||
//
|
||||
// License Servers
|
||||
// QA - early test server (corporate access only, not generally usable).
|
||||
// UAT - test server with non-production data.
|
||||
// Staging - test server with access to production data.
|
||||
// Production - live, production server.
|
||||
// Google Play - Allows testing on Google Play servers (very stale).
|
||||
//
|
||||
// Provisioning Servers
|
||||
// UAT - early access provisioning server.
|
||||
// Staging - early access to features.
|
||||
// Production - live production server.
|
||||
|
||||
// Useful configurations
|
||||
namespace wvcdm {
|
||||
typedef enum {
|
||||
kGooglePlayServer,
|
||||
kContentProtectionUatServer,
|
||||
kContentProtectionStagingServer,
|
||||
kContentProtectionTestQAServer,
|
||||
} LicenseServerId;
|
||||
kGooglePlayServer, // not tested recently
|
||||
kContentProtectionProdLicense,
|
||||
kContentProtectionUatLicense,
|
||||
kContentProtectionStagingLicense,
|
||||
kContentProtectionProdPlusProv30,
|
||||
kContentProtectionUatPlusProv30,
|
||||
kContentProtectionStagingPlusProv30,
|
||||
} ServerConfigurationId;
|
||||
|
||||
// Configures default test environment.
|
||||
class ConfigTestEnv {
|
||||
public:
|
||||
typedef struct {
|
||||
LicenseServerId id;
|
||||
std::string url;
|
||||
ServerConfigurationId id;
|
||||
std::string license_server_url;
|
||||
std::string license_service_certificate;
|
||||
std::string client_tag;
|
||||
std::string key_id;
|
||||
std::string offline_key_id;
|
||||
std::string service_certificate;
|
||||
std::string provisioning_server;
|
||||
std::string provisioning_server_url;
|
||||
std::string provisioning_service_certificate;
|
||||
} LicenseServerConfiguration;
|
||||
|
||||
explicit ConfigTestEnv(LicenseServerId server_id);
|
||||
ConfigTestEnv(LicenseServerId server_id, bool streaming);
|
||||
ConfigTestEnv(LicenseServerId server_id, bool streaming, bool renew,
|
||||
explicit ConfigTestEnv(ServerConfigurationId server_id);
|
||||
ConfigTestEnv(ServerConfigurationId server_id, bool streaming);
|
||||
ConfigTestEnv(ServerConfigurationId server_id, bool streaming, bool renew,
|
||||
bool release);
|
||||
~ConfigTestEnv() {};
|
||||
|
||||
@@ -40,8 +60,11 @@ class ConfigTestEnv {
|
||||
const std::string& provisioning_server() const {
|
||||
return provisioning_server_;
|
||||
}
|
||||
const std::string& service_certificate() const {
|
||||
return service_certificate_;
|
||||
const std::string& license_service_certificate() const {
|
||||
return license_service_certificate_;
|
||||
}
|
||||
const std::string& provisioning_service_certificate() const {
|
||||
return provisioning_service_certificate_;
|
||||
}
|
||||
const KeyId& wrong_key_id() const { return wrong_key_id_; }
|
||||
|
||||
@@ -54,14 +77,15 @@ class ConfigTestEnv {
|
||||
}
|
||||
|
||||
private:
|
||||
void Init(LicenseServerId server_id);
|
||||
void Init(ServerConfigurationId server_id);
|
||||
|
||||
std::string client_auth_;
|
||||
KeyId key_id_;
|
||||
CdmKeySystem key_system_;
|
||||
std::string license_server_;
|
||||
std::string provisioning_server_;
|
||||
std::string service_certificate_;
|
||||
std::string license_service_certificate_;
|
||||
std::string provisioning_service_certificate_;
|
||||
KeyId wrong_key_id_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(ConfigTestEnv);
|
||||
|
||||
@@ -124,6 +124,7 @@ struct LicenseInfo {
|
||||
int64_t grace_period_end_time;
|
||||
std::string app_parameters;
|
||||
std::string usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
std::string file_data;
|
||||
};
|
||||
|
||||
@@ -230,9 +231,9 @@ LicenseInfo license_test_data[] = {
|
||||
"0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF"
|
||||
"A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0"
|
||||
"BEA6CABACA1C2C"),
|
||||
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "",
|
||||
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "", 0,
|
||||
a2bs_hex(
|
||||
"0AAC150802100122A5150801121408011210303132333435363738394142434445461"
|
||||
"0AAE150802100122A7150801121408011210303132333435363738394142434445461"
|
||||
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
|
||||
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
|
||||
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
|
||||
@@ -311,8 +312,9 @@ LicenseInfo license_test_data[] = {
|
||||
"106B63746C0000000000ECDCBE0000000020DBDFA68F051A20182F029E35047A3841F"
|
||||
"A176C74E5B387350E8D58DEA6878FF0BEA6CABACA1C2C3A2E68747470733A2F2F7465"
|
||||
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
|
||||
"3654000480058006200122039CB77169260F923E5D4BA5BBF6A7611117483253F2869"
|
||||
"9DF3D9D14C3718E309")},
|
||||
"365400048005800620068001220785CE1756656A049E77F28C8449AB2DD115B6C43B2"
|
||||
"FF232D23F98B72F1DCE96A"
|
||||
)},
|
||||
|
||||
// license 1
|
||||
{"ksidC8EAA2579A282EB0", DeviceFiles::kLicenseStateReleasing,
|
||||
@@ -415,8 +417,9 @@ LicenseInfo license_test_data[] = {
|
||||
a2bs_hex(
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
|
||||
"22232425262728292a2b2c2d2e2f"),
|
||||
5,
|
||||
a2bs_hex(
|
||||
"0AF5150802100122EE150802121408011210303132333435363738394142434445461"
|
||||
"0AF7150802100122F0150802121408011210303132333435363738394142434445461"
|
||||
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
|
||||
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
|
||||
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
|
||||
@@ -497,8 +500,8 @@ LicenseInfo license_test_data[] = {
|
||||
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
|
||||
"36540F8ACD1910148E58ED29101520F0A054E616D6531120656616C75653158006230"
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212"
|
||||
"2232425262728292A2B2C2D2E2F1220312487214ACA5A9AF5ED9D45F209DC77E03CA1"
|
||||
"DBFFDF86C44A35A1351CE968B9")},
|
||||
"2232425262728292A2B2C2D2E2F6805122010DB816A045F2AA5865B17FE2F20DA2114"
|
||||
"17B2F8B2D7511C9DE89A87CB5208AB")},
|
||||
|
||||
// license 2
|
||||
{"ksidE8C37662C88DC673", DeviceFiles::kLicenseStateReleasing,
|
||||
@@ -601,8 +604,9 @@ LicenseInfo license_test_data[] = {
|
||||
a2bs_hex(
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
|
||||
"22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"),
|
||||
12,
|
||||
a2bs_hex(
|
||||
"0AAB160802100122A4160802121408011210303132333435363738394142434445461"
|
||||
"0AAD160802100122A6160802121408011210303132333435363738394142434445461"
|
||||
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
|
||||
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
|
||||
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
|
||||
@@ -684,8 +688,9 @@ LicenseInfo license_test_data[] = {
|
||||
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910152150A054E616D6531120C5661"
|
||||
"6C756531204E616D653252160A0C4E616D653220506172616D321206506172616D325"
|
||||
"8006240000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E"
|
||||
"1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F122"
|
||||
"07CEAAE401B81E635808AC830A0F3F43308A38FAB16069E542F994B6EC1325280")}};
|
||||
"1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F680"
|
||||
"C12206AA0237760D1F06E5CB78F5AFC3D124BBF7C26921CB3CC2EA44766801E25D34"
|
||||
"F")}};
|
||||
|
||||
// Sample license data and related data for storage and use for offline
|
||||
// playback. The license data and URLs in this test are not real.
|
||||
@@ -792,8 +797,9 @@ LicenseInfo license_update_test_data[] = {
|
||||
a2bs_hex(
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
|
||||
"22232425262728292a2b2c2d2e2f"),
|
||||
15,
|
||||
a2bs_hex(
|
||||
"0AEC150802100122E5150801121408011210303132333435363738394142434445461"
|
||||
"0AEE150802100122E7150801121408011210303132333435363738394142434445461"
|
||||
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
|
||||
"7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82"
|
||||
"6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD"
|
||||
@@ -874,14 +880,14 @@ LicenseInfo license_update_test_data[] = {
|
||||
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
|
||||
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910158006230000102030405060708"
|
||||
"090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2"
|
||||
"B2C2D2E2F1220A33C179B7718632337DFDC32D3711FD543336EBE838979DFDEB3A168"
|
||||
"BC9AFB27")},
|
||||
"B2C2D2E2F680F122009B8588A8E9926339289BA373DB8479A71F7AA1164083D90613F"
|
||||
"766D60B07CBC")},
|
||||
// license being released. all fields are identical except for license
|
||||
// state and hashed file data
|
||||
{"", DeviceFiles::kLicenseStateReleasing, "", "", "", "", "", "", 0, 0, 0,
|
||||
"", "",
|
||||
"", "", 15,
|
||||
a2bs_hex(
|
||||
"0AEC150802100122E5150802121408011210303132333435363738394142434445461"
|
||||
"0AEE150802100122E7150802121408011210303132333435363738394142434445461"
|
||||
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
|
||||
"7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82"
|
||||
"6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD"
|
||||
@@ -962,8 +968,8 @@ LicenseInfo license_update_test_data[] = {
|
||||
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
|
||||
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910158006230000102030405060708"
|
||||
"090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2"
|
||||
"B2C2D2E2F1220394BA01DFB519C1A7311115F8B2A0AC3141F981FFEA09FCD48A8EFA3"
|
||||
"A045AAE6")}};
|
||||
"B2C2D2E2F680F12202F5B77A3168AC2A81832231A435D0587F6D1DF3B905A7058C5E8"
|
||||
"565C81B96CA6")}};
|
||||
|
||||
// Application parameters were added to the License message. This data
|
||||
// is used to verify that a License saved without application parameters can
|
||||
@@ -1065,7 +1071,7 @@ LicenseInfo license_app_parameters_backwards_compatibility_test_data = {
|
||||
"0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF"
|
||||
"A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0"
|
||||
"BEA6CABACA1C2C"),
|
||||
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "",
|
||||
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "", 0,
|
||||
a2bs_hex(
|
||||
"0AA8150802100122A1150801121408011210303132333435363738394142434445461"
|
||||
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
|
||||
@@ -1154,11 +1160,12 @@ struct UsageInfo {
|
||||
std::string license_request;
|
||||
std::string license;
|
||||
std::string usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
std::string file_data;
|
||||
};
|
||||
|
||||
UsageInfo kUsageInfoTestData[] = {
|
||||
{"", "", "", "", // 0 usage info records
|
||||
{"", "", "", "", 0, // 0 usage info records
|
||||
a2bs_hex("0A06080210012A00122095053501C5FA405B7EF01DA94685C6B20CB36493"
|
||||
"A9CF1653B720E2BEA3B77929")},
|
||||
{// 1 usage info record
|
||||
@@ -1196,6 +1203,7 @@ UsageInfo kUsageInfoTestData[] = {
|
||||
a2bs_hex(
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
|
||||
"22232425262728292a2b2c2d2e2f"),
|
||||
6,
|
||||
a2bs_hex(
|
||||
"0AB307080210012AAC070AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE"
|
||||
"1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D"
|
||||
@@ -1261,6 +1269,7 @@ UsageInfo kUsageInfoTestData[] = {
|
||||
a2bs_hex(
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
|
||||
"22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"),
|
||||
14,
|
||||
a2bs_hex(
|
||||
"0ADF0E080210012AD80E0AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE"
|
||||
"1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D"
|
||||
@@ -1353,6 +1362,7 @@ UsageInfo kUsageInfoTestData[] = {
|
||||
a2bs_hex(
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021"
|
||||
"22232425262728292a2b2c2d2e2f"),
|
||||
19,
|
||||
a2bs_hex(
|
||||
"0A8B16080210012A84160AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE"
|
||||
"1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D"
|
||||
@@ -1465,88 +1475,82 @@ HlsAttributesInfo kHlsAttributesTestData[] = {
|
||||
// Usage Table and Entry Test Data
|
||||
// Note: Make sure the number of entries in kUsageEntriesTestData and
|
||||
// kUsageTableInfoTestData are equal.
|
||||
DeviceFiles::UsageEntryInfo kUsageEntriesTestData[] = {
|
||||
CdmUsageEntryInfo kUsageEntriesTestData[] = {
|
||||
// usage entry 0
|
||||
{
|
||||
DeviceFiles::kStorageLicense, "ksid0", "", "",
|
||||
kStorageLicense, "ksid0", "",
|
||||
},
|
||||
// usage entry 1
|
||||
{
|
||||
DeviceFiles::kStorageLicense, "ksid1", "", "",
|
||||
kStorageLicense, "ksid1", "",
|
||||
},
|
||||
// usage entry 2
|
||||
{
|
||||
DeviceFiles::kStorageUsageInfo, "", "provider_session_token_2",
|
||||
"app_id_2",
|
||||
kStorageUsageInfo, "", "app_id_2",
|
||||
},
|
||||
// usage entry 3
|
||||
{
|
||||
DeviceFiles::kStorageUsageInfo, "", "provider_session_token_3",
|
||||
"app_id_3",
|
||||
kStorageUsageInfo, "", "app_id_3",
|
||||
},
|
||||
// usage entry 4
|
||||
{
|
||||
DeviceFiles::kStorageLicense, "ksid4", "", "",
|
||||
kStorageLicense, "ksid4", "",
|
||||
},
|
||||
// usage entry 5
|
||||
{
|
||||
DeviceFiles::kStorageUsageInfo, "", "provider_session_token_5",
|
||||
"app_id_5",
|
||||
kStorageUsageInfo, "", "app_id_5",
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
struct UsageTableTestInfo {
|
||||
std::string usage_table_header;
|
||||
CdmUsageTableHeader usage_table_header;
|
||||
std::string file_data;
|
||||
};
|
||||
|
||||
UsageTableTestInfo kUsageTableInfoTestData[] = {
|
||||
// usage table 0
|
||||
|
||||
{a2bs_hex("5574517CCC"),
|
||||
a2bs_hex("0A18080510013A120A055574517CCC1209080112056B73696430122018268E3F"
|
||||
"384F28D04BEE00304089C000463C22E987532855390915FD02C36B5C")},
|
||||
// usage table 1
|
||||
{a2bs_hex("CA870203010001288001"),
|
||||
a2bs_hex("0A28080510013A220A0ACA8702030100012880011209080112056B7369643012"
|
||||
"09080112056B7369643112202D3638164ADC3B4276734A8EDE96C40BFE14DDB2"
|
||||
"8013337A3A1A9DFC09F34923")},
|
||||
a2bs_hex("0A2C080510013A260A0ACA870203010001288001120B080112056B736964301A"
|
||||
"00120B080112056B736964311A00122049A8F3481444A5B64B6C4F05FBCC2EF8"
|
||||
"CB67444A08654763F2F5B80F658D7B38")},
|
||||
// usage table 2
|
||||
{a2bs_hex("7A7D507618A5D3A68F05228E023082010A028201"),
|
||||
a2bs_hex("0A5A080510013A540A147A7D507618A5D3A68F05228E023082010A0282011209"
|
||||
"080112056B736964301209080112056B73696431122608021A1870726F766964"
|
||||
"65725F73657373696F6E5F746F6B656E5F3222086170705F69645F321220CB07"
|
||||
"CA08A1E76C61A5F45067176B960A9DB40D169025AF245CF1AFC66C979F47")},
|
||||
a2bs_hex("0A46080510013A400A147A7D507618A5D3A68F05228E023082010A028201120B"
|
||||
"080112056B736964301A00120B080112056B736964311A00120E080212001A08"
|
||||
"6170705F69645F321220783E93A02223BDB94E743856C0F69C35B213ACCDDE91"
|
||||
"93E48E9186AA83B80584")},
|
||||
// usage table 3
|
||||
{a2bs_hex("E83A4902772DAFD2740B7748E9C3B1752D6F12859CED07E82969B4EC"),
|
||||
a2bs_hex("0A8B01080510013A84010A1CE83A4902772DAFD2740B7748E9C3B1752D6F1285"
|
||||
"9CED07E82969B4EC1209080112056B736964301209080112056B736964311226"
|
||||
"08021A1870726F76696465725F73657373696F6E5F746F6B656E5F3222086170"
|
||||
"705F69645F32122608021A1870726F76696465725F73657373696F6E5F746F6B"
|
||||
"656E5F3322086170705F69645F331220C4157F80E81C923A9F0885CE6B928D15"
|
||||
"7E1648384C3E44F04A966815EB09B260")},
|
||||
a2bs_hex("0A5E080510013A580A1CE83A4902772DAFD2740B7748E9C3B1752D6F12859CED"
|
||||
"07E82969B4EC120B080112056B736964301A00120B080112056B736964311A00"
|
||||
"120E080212001A086170705F69645F32120E080212001A086170705F69645F33"
|
||||
"122084E67F1338727291BC3D92E28442DC8B0F44CB5AF7B98A799313B7EB7F55"
|
||||
"ED18")},
|
||||
// usage table 4
|
||||
{a2bs_hex("CA870203010001288001300112800250D1F8B1ECF849B60FF93E37C4DEEF"
|
||||
"52F1CCFC047EF42300131F9C4758F4"),
|
||||
a2bs_hex("0AA701080510013AA0010A2DCA870203010001288001300112800250D1F8B1EC"
|
||||
"F849B60FF93E37C4DEEF52F1CCFC047EF42300131F9C4758F41209080112056B"
|
||||
"736964301209080112056B73696431122608021A1870726F76696465725F7365"
|
||||
"7373696F6E5F746F6B656E5F3222086170705F69645F32122608021A1870726F"
|
||||
"76696465725F73657373696F6E5F746F6B656E5F3322086170705F69645F3312"
|
||||
"09080112056B7369643412203F75C53693E7A3DC9BA5BF3E23D7EFCF3C05687A"
|
||||
"A6082E3AB78F563525981999")},
|
||||
a2bs_hex("0A7C080510013A760A2DCA870203010001288001300112800250D1F8B1ECF849"
|
||||
"B60FF93E37C4DEEF52F1CCFC047EF42300131F9C4758F4120B080112056B7369"
|
||||
"64301A00120B080112056B736964311A00120E080212001A086170705F69645F"
|
||||
"32120E080212001A086170705F69645F33120B080112056B736964341A001220"
|
||||
"1CDFCFED5E58A1DF77E1B335305424E1F0260340F9CC15985684C43A4207652"
|
||||
"1")},
|
||||
// usage table 5
|
||||
{a2bs_hex("EC83A4902772DAFD2740B7748E9C3B1752D6F12859CED07E8882969B433E"
|
||||
"C29AC6FDBE79230B0FAED5D94CF6B829A420BBE3270323941776EE60DD6B"),
|
||||
a2bs_hex("0ADE01080510013AD7010A3CEC83A4902772DAFD2740B7748E9C3B1752D6F128"
|
||||
a2bs_hex("0A9C01080510013A95010A3CEC83A4902772DAFD2740B7748E9C3B1752D6F128"
|
||||
"59CED07E8882969B433EC29AC6FDBE79230B0FAED5D94CF6B829A420BBE32703"
|
||||
"23941776EE60DD6B1209080112056B736964301209080112056B736964311226"
|
||||
"08021A1870726F76696465725F73657373696F6E5F746F6B656E5F3222086170"
|
||||
"705F69645F32122608021A1870726F76696465725F73657373696F6E5F746F6B"
|
||||
"656E5F3322086170705F69645F331209080112056B73696434122608021A1870"
|
||||
"726F76696465725F73657373696F6E5F746F6B656E5F3522086170705F69645F"
|
||||
"3512203B35BD5C615BBA79008A7A1DA29AFA69F5CD529DFDE794A0544E423B72"
|
||||
"1CB8E8")},
|
||||
"23941776EE60DD6B120B080112056B736964301A00120B080112056B73696431"
|
||||
"1A00120E080212001A086170705F69645F32120E080212001A086170705F6964"
|
||||
"5F33120B080112056B736964341A00120E080212001A086170705F69645F3512"
|
||||
"20305C7A27A918268119E1996FC182C153DF805034A387F90C3585749E764731"
|
||||
"32")},
|
||||
};
|
||||
|
||||
class MockFile : public File {
|
||||
@@ -1889,7 +1893,8 @@ TEST_P(DeviceFilesStoreTest, StoreLicense) {
|
||||
license_test_data[license_num].playback_start_time,
|
||||
license_test_data[license_num].last_playback_time,
|
||||
license_test_data[license_num].grace_period_end_time, app_parameters,
|
||||
license_test_data[license_num].usage_entry));
|
||||
license_test_data[license_num].usage_entry,
|
||||
license_test_data[license_num].usage_entry_number));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(StoreLicense, DeviceFilesStoreTest, ::testing::Bool());
|
||||
@@ -1939,7 +1944,8 @@ TEST_F(DeviceFilesTest, StoreLicenses) {
|
||||
license_test_data[i].playback_start_time,
|
||||
license_test_data[i].last_playback_time,
|
||||
license_test_data[i].grace_period_end_time, app_parameters,
|
||||
license_test_data[i].usage_entry));
|
||||
license_test_data[i].usage_entry,
|
||||
license_test_data[i].usage_entry_number));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1981,6 +1987,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
|
||||
std::string release_server_url;
|
||||
CdmAppParameterMap app_parameters;
|
||||
std::string usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
|
||||
for (size_t i = 0; i < kNumberOfLicenses; i++) {
|
||||
DeviceFiles::LicenseState license_state;
|
||||
@@ -1989,7 +1996,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
|
||||
&key_request, &key_response, &key_renewal_request,
|
||||
&key_renewal_response, &release_server_url, &playback_start_time,
|
||||
&last_playback_time, &grace_period_end_time, &app_parameters,
|
||||
&usage_entry));
|
||||
&usage_entry, &usage_entry_number));
|
||||
EXPECT_EQ(license_test_data[i].license_state, license_state);
|
||||
EXPECT_EQ(license_test_data[i].pssh_data, pssh_data);
|
||||
EXPECT_EQ(license_test_data[i].key_request, key_request);
|
||||
@@ -2001,6 +2008,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
|
||||
EXPECT_EQ(license_test_data[i].grace_period_end_time,
|
||||
grace_period_end_time);
|
||||
EXPECT_EQ(license_test_data[i].usage_entry, usage_entry);
|
||||
EXPECT_EQ(license_test_data[i].usage_entry_number, usage_entry_number);
|
||||
|
||||
std::map<std::string, std::string>::iterator itr;
|
||||
for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) {
|
||||
@@ -2049,12 +2057,14 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
|
||||
std::string release_server_url;
|
||||
CdmAppParameterMap app_parameters;
|
||||
std::string usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
|
||||
EXPECT_TRUE(device_files.RetrieveLicense(
|
||||
test_data->key_set_id, &license_state, &pssh_data, &key_request,
|
||||
&key_response, &key_renewal_request, &key_renewal_response,
|
||||
&release_server_url, &playback_start_time, &last_playback_time,
|
||||
&grace_period_end_time, &app_parameters, &usage_entry));
|
||||
&grace_period_end_time, &app_parameters, &usage_entry,
|
||||
&usage_entry_number));
|
||||
EXPECT_EQ(test_data->license_state, license_state);
|
||||
EXPECT_EQ(test_data->pssh_data, pssh_data);
|
||||
EXPECT_EQ(test_data->key_request, key_request);
|
||||
@@ -2066,6 +2076,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
|
||||
EXPECT_EQ(test_data->grace_period_end_time, grace_period_end_time);
|
||||
EXPECT_EQ(0u, app_parameters.size());
|
||||
EXPECT_EQ(test_data->usage_entry, usage_entry);
|
||||
EXPECT_EQ(test_data->usage_entry_number, usage_entry_number);
|
||||
}
|
||||
|
||||
TEST_F(DeviceFilesTest, UpdateLicenseState) {
|
||||
@@ -2102,7 +2113,8 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) {
|
||||
license_update_test_data[0].last_playback_time,
|
||||
license_update_test_data[0].grace_period_end_time,
|
||||
GetAppParameters(license_test_data[0].app_parameters),
|
||||
license_update_test_data[0].usage_entry));
|
||||
license_update_test_data[0].usage_entry,
|
||||
license_update_test_data[0].usage_entry_number));
|
||||
|
||||
EXPECT_TRUE(device_files.StoreLicense(
|
||||
license_update_test_data[0].key_set_id,
|
||||
@@ -2117,7 +2129,8 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) {
|
||||
license_update_test_data[0].last_playback_time,
|
||||
license_update_test_data[0].grace_period_end_time,
|
||||
GetAppParameters(license_test_data[0].app_parameters),
|
||||
license_update_test_data[0].usage_entry));
|
||||
license_update_test_data[0].usage_entry,
|
||||
license_update_test_data[0].usage_entry_number));
|
||||
}
|
||||
|
||||
TEST_F(DeviceFilesTest, DeleteLicense) {
|
||||
@@ -2158,12 +2171,14 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
|
||||
int64_t playback_start_time, last_playback_time, grace_period_end_time;
|
||||
CdmAppParameterMap app_parameters;
|
||||
std::string usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
|
||||
EXPECT_TRUE(device_files.RetrieveLicense(
|
||||
license_test_data[0].key_set_id, &license_state, &pssh_data, &key_request,
|
||||
&key_response, &key_renewal_request, &key_renewal_response,
|
||||
&release_server_url, &playback_start_time, &last_playback_time,
|
||||
&grace_period_end_time, &app_parameters, &usage_entry));
|
||||
&grace_period_end_time, &app_parameters, &usage_entry,
|
||||
&usage_entry_number));
|
||||
EXPECT_EQ(license_test_data[0].license_state, license_state);
|
||||
EXPECT_EQ(license_test_data[0].pssh_data, pssh_data);
|
||||
EXPECT_EQ(license_test_data[0].key_request, key_request);
|
||||
@@ -2181,6 +2196,7 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
|
||||
std::string::npos);
|
||||
}
|
||||
EXPECT_EQ(license_test_data[0].usage_entry, usage_entry);
|
||||
EXPECT_EQ(license_test_data[0].usage_entry_number, usage_entry_number);
|
||||
|
||||
EXPECT_TRUE(device_files.DeleteLicense(license_test_data[0].key_set_id));
|
||||
EXPECT_FALSE(device_files.LicenseExists(license_test_data[0].key_set_id));
|
||||
@@ -2235,7 +2251,9 @@ TEST_P(DeviceFilesUsageInfoTest, Read) {
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
std::vector<std::pair<CdmKeyMessage, CdmKeyResponse> > license_info;
|
||||
ASSERT_TRUE(device_files.RetrieveUsageInfo(app_id, &license_info));
|
||||
ASSERT_TRUE(device_files.RetrieveUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&license_info));
|
||||
if (index >= 0) {
|
||||
EXPECT_EQ(static_cast<size_t>(index), license_info.size());
|
||||
for (size_t i = 0; i < license_info.size(); ++i) {
|
||||
@@ -2263,6 +2281,7 @@ TEST_P(DeviceFilesUsageInfoTest, Store) {
|
||||
std::string license(GenerateRandomData(kLicenseLen));
|
||||
std::string key_set_id(GenerateRandomData(kKeySetIdLen));
|
||||
std::string usage_entry(GenerateRandomData(kUsageEntryLen));
|
||||
uint32_t usage_entry_number = 16;
|
||||
std::string path =
|
||||
device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id);
|
||||
|
||||
@@ -2300,8 +2319,10 @@ TEST_P(DeviceFilesUsageInfoTest, Store) {
|
||||
DeviceFiles device_files(&file_system);
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
ASSERT_TRUE(device_files.StoreUsageInfo(pst, license_request, license, app_id,
|
||||
key_set_id, usage_entry));
|
||||
ASSERT_TRUE(device_files.StoreUsageInfo(
|
||||
pst, license_request, license,
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
key_set_id, usage_entry, usage_entry_number));
|
||||
}
|
||||
|
||||
TEST_P(DeviceFilesUsageInfoTest, Delete) {
|
||||
@@ -2349,9 +2370,13 @@ TEST_P(DeviceFilesUsageInfoTest, Delete) {
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
if (index >= 1) {
|
||||
ASSERT_TRUE(device_files.DeleteUsageInfo(app_id, pst));
|
||||
ASSERT_TRUE(device_files.DeleteUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
pst));
|
||||
} else {
|
||||
ASSERT_FALSE(device_files.DeleteUsageInfo(app_id, pst));
|
||||
ASSERT_FALSE(device_files.DeleteUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
pst));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2385,7 +2410,9 @@ TEST_P(DeviceFilesUsageInfoTest, DeleteAll) {
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
std::vector<std::string> psts;
|
||||
ASSERT_TRUE(device_files.DeleteAllUsageInfoForApp(app_id, &psts));
|
||||
ASSERT_TRUE(device_files.DeleteAllUsageInfoForApp(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&psts));
|
||||
if (index < 0) {
|
||||
EXPECT_EQ(0u, psts.size());
|
||||
} else {
|
||||
@@ -2479,20 +2506,14 @@ TEST_P(DeviceFilesUsageTableTest, Store) {
|
||||
|
||||
size_t entry_data_length = 0;
|
||||
std::vector<std::string> entry_data;
|
||||
std::vector<DeviceFiles::UsageEntryInfo> usage_entry_info;
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info;
|
||||
usage_entry_info.resize(index + 1);
|
||||
for (int i = 0; i <= index; ++i) {
|
||||
usage_entry_info[i] = kUsageEntriesTestData[i];
|
||||
if (kUsageEntriesTestData[i].storage_type == DeviceFiles::kStorageLicense) {
|
||||
entry_data.push_back(kUsageEntriesTestData[i].key_set_id);
|
||||
entry_data_length += kUsageEntriesTestData[i].key_set_id.size();
|
||||
} else {
|
||||
entry_data.push_back(kUsageEntriesTestData[i].provider_session_token);
|
||||
entry_data.push_back(kUsageEntriesTestData[i].app_id);
|
||||
entry_data_length +=
|
||||
kUsageEntriesTestData[i].provider_session_token.size() +
|
||||
kUsageEntriesTestData[i].app_id.size();
|
||||
}
|
||||
entry_data.push_back(kUsageEntriesTestData[i].key_set_id);
|
||||
entry_data.push_back(kUsageEntriesTestData[i].usage_info_file_name);
|
||||
entry_data_length += kUsageEntriesTestData[i].key_set_id.size() +
|
||||
kUsageEntriesTestData[i].usage_info_file_name.size();
|
||||
}
|
||||
entry_data.push_back(kUsageTableInfoTestData[index].usage_table_header);
|
||||
entry_data_length += kUsageTableInfoTestData[index].usage_table_header.size();
|
||||
@@ -2516,7 +2537,7 @@ TEST_P(DeviceFilesUsageTableTest, Store) {
|
||||
TEST_P(DeviceFilesUsageTableTest, Read) {
|
||||
MockFileSystem file_system;
|
||||
MockFile file;
|
||||
int index = GetParam();
|
||||
size_t index = GetParam();
|
||||
|
||||
std::string path = device_base_path_ + DeviceFiles::GetUsageTableFileName();
|
||||
|
||||
@@ -2535,28 +2556,22 @@ TEST_P(DeviceFilesUsageTableTest, Read) {
|
||||
DeviceFiles device_files(&file_system);
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
std::vector<DeviceFiles::UsageEntryInfo> usage_entry_info;
|
||||
std::string usage_table_header;
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info;
|
||||
CdmUsageTableHeader usage_table_header;
|
||||
ASSERT_TRUE(device_files.RetrieveUsageTableInfo(&usage_table_header,
|
||||
&usage_entry_info));
|
||||
EXPECT_EQ(kUsageTableInfoTestData[index].usage_table_header,
|
||||
usage_table_header);
|
||||
EXPECT_EQ(index + 1u, usage_entry_info.size());
|
||||
|
||||
for (int i = 0; i <= index; ++i) {
|
||||
for (size_t i = 0; i <= index; ++i) {
|
||||
EXPECT_EQ(kUsageEntriesTestData[i].storage_type,
|
||||
usage_entry_info[i].storage_type);
|
||||
if (usage_entry_info[i].storage_type == DeviceFiles::kStorageLicense) {
|
||||
EXPECT_EQ(kUsageEntriesTestData[i].key_set_id,
|
||||
usage_entry_info[i].key_set_id);
|
||||
EXPECT_EQ(kEmptyString, usage_entry_info[i].provider_session_token);
|
||||
EXPECT_EQ(kEmptyString, usage_entry_info[i].app_id);
|
||||
} else {
|
||||
EXPECT_EQ(kEmptyString, usage_entry_info[i].key_set_id);
|
||||
EXPECT_EQ(kUsageEntriesTestData[i].provider_session_token,
|
||||
usage_entry_info[i].provider_session_token);
|
||||
EXPECT_EQ(kUsageEntriesTestData[i].app_id, usage_entry_info[i].app_id);
|
||||
}
|
||||
EXPECT_EQ(kUsageEntriesTestData[i].key_set_id,
|
||||
usage_entry_info[i].key_set_id);
|
||||
EXPECT_EQ(
|
||||
kUsageEntriesTestData[i].usage_info_file_name,
|
||||
usage_entry_info[i].usage_info_file_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,50 @@ namespace {
|
||||
const std::string kKeySystem = "com.widevine.alpha";
|
||||
|
||||
std::string g_provisioning_server;
|
||||
std::string g_service_certificate;
|
||||
std::string g_license_service_certificate;
|
||||
std::string g_provisioning_service_certificate;
|
||||
|
||||
/*
|
||||
* Locate the portion of the server's response message that is between
|
||||
* the strings jason_start_substr and json_end_substr. Returns the string
|
||||
* through *result. If the start substring match fails, assume the entire
|
||||
* string represents a serialized protobuf mesaage and return true with
|
||||
* the entire string. If the end_substring match fails, return false with
|
||||
* an empty *result.
|
||||
*/
|
||||
bool ExtractSignedMessage(const std::string& response,
|
||||
const std::string& json_start_substr,
|
||||
const std::string& json_end_substr,
|
||||
std::string* result) {
|
||||
std::string b64_string;
|
||||
size_t start = response.find(json_start_substr);
|
||||
|
||||
if (start == response.npos) {
|
||||
// Assume web safe protobuf
|
||||
b64_string.assign(response);
|
||||
} else {
|
||||
// Assume JSON-wrapped protobuf
|
||||
size_t end = response.find(json_end_substr,
|
||||
start + json_start_substr.length());
|
||||
if (end == response.npos) {
|
||||
LOGE("ExtractSignedMessage cannot locate end substring");
|
||||
result->clear();
|
||||
return false;
|
||||
}
|
||||
size_t b64_string_size = end - start - json_start_substr.length();
|
||||
b64_string.assign(response, start + json_start_substr.length(),
|
||||
b64_string_size);
|
||||
}
|
||||
|
||||
if (b64_string.empty()) {
|
||||
LOGE("Response message is empty");
|
||||
result->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
result->swap(b64_string);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -38,13 +81,11 @@ class WvGenericOperationsTest : public testing::Test {
|
||||
virtual void SetUp() {
|
||||
::testing::Test::SetUp();
|
||||
|
||||
#if defined(QA_TEST_SERVER)
|
||||
ConfigTestEnv config(kContentProtectionTestQAServer);
|
||||
#else
|
||||
ConfigTestEnv config(kContentProtectionUatServer);
|
||||
#endif // !defined(QA_TEST_SERVER)
|
||||
ConfigTestEnv config(kContentProtectionStagingPlusProv30);
|
||||
|
||||
g_service_certificate.assign(config.service_certificate());
|
||||
g_provisioning_service_certificate.assign(
|
||||
config.provisioning_service_certificate());
|
||||
g_license_service_certificate.assign(config.license_service_certificate());
|
||||
g_provisioning_server.assign(config.provisioning_server());
|
||||
|
||||
cdm_engine_ = NULL;
|
||||
@@ -52,15 +93,13 @@ class WvGenericOperationsTest : public testing::Test {
|
||||
// TODO(fredgc or gmorgan): This should be updated for provisioning 3.0
|
||||
// Load test keybox. This keybox will be used by any CryptoSession
|
||||
// created by the CDM under test.
|
||||
#if defined(PROVISIONING_30)
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestRSAKey());
|
||||
#else
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestKeybox());
|
||||
#endif // !defined(PROVISIONING_30)
|
||||
|
||||
// Perform CdmEngine setup
|
||||
cdm_engine_ = new CdmEngine(&file_system_);
|
||||
|
||||
Provision();
|
||||
|
||||
CdmResponseType status =
|
||||
cdm_engine_->OpenSession(kKeySystem, NULL, NULL, &session_id_);
|
||||
if (status == NEED_PROVISIONING) {
|
||||
@@ -177,29 +216,55 @@ class WvGenericOperationsTest : public testing::Test {
|
||||
}
|
||||
|
||||
protected:
|
||||
void Provision() {
|
||||
|
||||
virtual void Provision() {
|
||||
LOGE("WvCdmEnginePreProvTest::Provision: url=%s",
|
||||
g_provisioning_server.c_str());
|
||||
CdmProvisioningRequest prov_request;
|
||||
std::string provisioning_server_url;
|
||||
CdmCertificateType cert_type = kCertificateWidevine;
|
||||
std::string cert_authority;
|
||||
std::string cert, wrapped_key;
|
||||
cdm_engine_->SetServiceCertificate(g_service_certificate);
|
||||
ASSERT_EQ(NO_ERROR,
|
||||
cdm_engine_->GetProvisioningRequest(
|
||||
cert_type, cert_authority, &prov_request,
|
||||
&provisioning_server_url));
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine_->SetServiceCertificate(
|
||||
g_provisioning_service_certificate));
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine_->GetProvisioningRequest(
|
||||
cert_type, cert_authority, &prov_request,
|
||||
&provisioning_server_url));
|
||||
|
||||
LOGV("WvCdmEnginePreProvTest::Provision: req=%s", prov_request.c_str());
|
||||
|
||||
// Ignore URL provided by CdmEngine. Use ours, as configured
|
||||
// for test vs. production server.
|
||||
provisioning_server_url.assign(g_provisioning_server);
|
||||
UrlRequest url_request(provisioning_server_url);
|
||||
EXPECT_TRUE(url_request.is_connected());
|
||||
url_request.PostCertRequestInQueryString(prov_request);
|
||||
std::string message;
|
||||
bool ok = url_request.GetResponse(&message);
|
||||
std::string http_message;
|
||||
bool ok = url_request.GetResponse(&http_message);
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
LOGV("WvCdmEnginePreProvTest::Provision: http_message: \n%s\n",
|
||||
http_message.c_str());
|
||||
|
||||
// extract provisioning response from received message
|
||||
// Extracts signed response from JSON string, decodes base64 signed response
|
||||
const std::string kMessageStart = "\"signedResponse\": \"";
|
||||
const std::string kMessageEnd = "\"";
|
||||
std::string base64_response;
|
||||
EXPECT_TRUE (ExtractSignedMessage(http_message, kMessageStart, kMessageEnd,
|
||||
&base64_response)) <<
|
||||
"Failed to extract signed serialized response from JSON response";
|
||||
|
||||
LOGV("WvCdmEnginePreProvTest::Provision: extracted response "
|
||||
"message: \n%s\n", base64_response.c_str());
|
||||
|
||||
ASSERT_EQ(NO_ERROR,
|
||||
cdm_engine_->HandleProvisioningResponse(message, &cert,
|
||||
&wrapped_key));
|
||||
cdm_engine_->HandleProvisioningResponse(base64_response,
|
||||
&cert, &wrapped_key));
|
||||
|
||||
ASSERT_EQ(NO_ERROR,
|
||||
cdm_engine_->SetServiceCertificate(
|
||||
g_license_service_certificate));
|
||||
}
|
||||
|
||||
// This CryptoSession object handles Initialization and Termination
|
||||
|
||||
Reference in New Issue
Block a user