Source release 16.4.0

This commit is contained in:
John W. Bruce
2020-10-09 16:08:56 -07:00
parent 160df9f57a
commit 9d17a531ee
562 changed files with 52913 additions and 37426 deletions

View File

@@ -0,0 +1,195 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
// These tests perform various end-to-end actions similar to what an application
// would do. They verify that policies specified on UAT are honored on the
// device.
#include <string>
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "cdm_engine.h"
#include "clock.h"
#include "config_test_env.h"
#include "initialization_data.h"
#include "license_request.h"
#include "log.h"
#include "metrics_collections.h"
#include "test_base.h"
#include "test_printers.h"
#include "test_sleep.h"
#include "url_request.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_types.h"
namespace wvcdm {
namespace {
constexpr int kHttpOk = 200;
const std::string kCencMimeType = "cenc";
} // namespace
// Core Policy Integration Test
class CorePIGTest : public WvCdmTestBaseWithEngine {
protected:
void SetUp() override {
WvCdmTestBase::SetUp();
EnsureProvisioned();
}
void OpenSession(CdmSessionId* session_id) {
CdmResponseType status = cdm_engine_.OpenSession(
config_.key_system(), nullptr, nullptr, session_id);
ASSERT_EQ(NO_ERROR, status);
ASSERT_TRUE(cdm_engine_.IsOpenSession(*session_id));
}
void CloseSession(const CdmSessionId& session_id) {
CdmResponseType status = cdm_engine_.CloseSession(session_id);
ASSERT_EQ(NO_ERROR, status);
ASSERT_FALSE(cdm_engine_.IsOpenSession(session_id));
}
// Create a license request for the given content_id and requesting the
// specified license_type.
void GenerateKeyRequest(const CdmSessionId& session_id,
const std::string& content_id,
CdmKeyRequest* key_request,
CdmLicenseType license_type) {
video_widevine::WidevinePsshData pssh;
pssh.set_content_id(content_id);
const std::string init_data_string = MakePSSH(pssh);
const InitializationData init_data(kCencMimeType, init_data_string);
init_data.DumpToLogs();
CdmAppParameterMap empty_app_parameters;
CdmKeySetId empty_key_set_id;
CdmResponseType result = cdm_engine_.GenerateKeyRequest(
session_id, empty_key_set_id, init_data, license_type,
empty_app_parameters, key_request);
ASSERT_EQ(KEY_MESSAGE, result);
ASSERT_EQ(kKeyRequestTypeInitial, key_request->type);
}
// Send the request to the server and get the response.
void GetKeyResponse(const CdmKeyRequest& key_request,
std::string* key_response) {
const std::string url = config_.license_server() + config_.client_auth();
UrlRequest url_request(url);
ASSERT_TRUE(url_request.is_connected());
std::string http_response;
url_request.PostRequest(key_request.message);
ASSERT_TRUE(url_request.GetResponse(&http_response));
int status_code = url_request.GetStatusCode(http_response);
ASSERT_EQ(kHttpOk, status_code);
LicenseRequest license_request;
license_request.GetDrmMessage(http_response, *key_response);
}
// Load the license response into the specified session. Verify it has the
// correct license type (either streaming or offline).
void AddKey(const CdmSessionId& session_id, const std::string& key_response,
CdmLicenseType expected_license_type, CdmKeySetId* key_set_id) {
CdmLicenseType license_type;
CdmResponseType status =
cdm_engine_.AddKey(session_id, key_response, &license_type, key_set_id);
ASSERT_EQ(KEY_ADDED, status);
ASSERT_EQ(expected_license_type, license_type);
}
// Reload the license response into the specified session.
void RestoreKey(const CdmSessionId& session_id,
const CdmKeySetId& key_set_id) {
CdmResponseType status = cdm_engine_.RestoreKey(session_id, key_set_id);
ASSERT_EQ(KEY_ADDED, status);
}
// Use the key to decrypt.
void Decrypt(const CdmSessionId& session_id, const KeyId& key_id) {
constexpr size_t buffer_size = 500;
const std::vector<uint8_t> input(buffer_size, 0);
std::vector<uint8_t> output(buffer_size, 0);
const std::vector<uint8_t> iv(KEY_IV_SIZE, 0);
Decrypt(session_id, key_id, input, iv, &output, NO_ERROR);
}
// Try to use the key to decrypt, but expect the key has expired.
void FailDecrypt(const CdmSessionId& session_id, const KeyId& key_id) {
constexpr size_t buffer_size = 500;
const std::vector<uint8_t> input(buffer_size, 0);
std::vector<uint8_t> output(buffer_size, 0);
const std::vector<uint8_t> iv(KEY_IV_SIZE, 0);
Decrypt(session_id, key_id, input, iv, &output, NEED_KEY);
}
void Decrypt(const CdmSessionId& session_id, const KeyId& key_id,
const std::vector<uint8_t>& input,
const std::vector<uint8_t>& iv, std::vector<uint8_t>* output,
CdmResponseType expected_status) {
CdmDecryptionParametersV16 params(key_id);
params.is_secure = false;
CdmDecryptionSample sample(input.data(), output->data(), 0, input.size(),
iv);
CdmDecryptionSubsample subsample(0, input.size());
sample.subsamples.push_back(subsample);
params.samples.push_back(sample);
CdmResponseType status = cdm_engine_.DecryptV16(session_id, params);
ASSERT_EQ(expected_status, status);
}
};
// An offline license with nonce not required.
TEST_F(CorePIGTest, OfflineNoNonce) {
const std::string content_id = "2015_tears";
const KeyId key_id = "0000000000000000";
const CdmLicenseType license_type = kLicenseTypeOffline;
CdmSessionId session_id;
ASSERT_NO_FATAL_FAILURE(OpenSession(&session_id));
CdmKeyRequest key_request;
ASSERT_NO_FATAL_FAILURE(
GenerateKeyRequest(session_id, content_id, &key_request, license_type));
std::string key_response;
ASSERT_NO_FATAL_FAILURE(GetKeyResponse(key_request, &key_response));
CdmKeySetId key_set_id;
ASSERT_NO_FATAL_FAILURE(
AddKey(session_id, key_response, license_type, &key_set_id));
ASSERT_NO_FATAL_FAILURE(Decrypt(session_id, key_id));
ASSERT_NO_FATAL_FAILURE(CloseSession(session_id));
ASSERT_NO_FATAL_FAILURE(OpenSession(&session_id));
ASSERT_NO_FATAL_FAILURE(RestoreKey(session_id, key_set_id));
ASSERT_NO_FATAL_FAILURE(Decrypt(session_id, key_id));
ASSERT_NO_FATAL_FAILURE(CloseSession(session_id));
}
// An offline license with nonce and provider session token.
TEST_F(CorePIGTest, OfflineWithPST) {
const std::string content_id = "offline_clip2";
const KeyId key_id =
"\x32\x60\xF3\x9E\x12\xCC\xF6\x53\x52\x99\x90\x16\x8A\x35\x83\xFF";
const CdmLicenseType license_type = kLicenseTypeOffline;
CdmSessionId session_id;
ASSERT_NO_FATAL_FAILURE(OpenSession(&session_id));
CdmKeyRequest key_request;
ASSERT_NO_FATAL_FAILURE(
GenerateKeyRequest(session_id, content_id, &key_request, license_type));
std::string key_response;
ASSERT_NO_FATAL_FAILURE(GetKeyResponse(key_request, &key_response));
CdmKeySetId key_set_id;
ASSERT_NO_FATAL_FAILURE(
AddKey(session_id, key_response, license_type, &key_set_id));
ASSERT_NO_FATAL_FAILURE(Decrypt(session_id, key_id));
ASSERT_NO_FATAL_FAILURE(CloseSession(session_id));
ASSERT_NO_FATAL_FAILURE(OpenSession(&session_id));
ASSERT_NO_FATAL_FAILURE(RestoreKey(session_id, key_set_id));
ASSERT_NO_FATAL_FAILURE(Decrypt(session_id, key_id));
ASSERT_NO_FATAL_FAILURE(CloseSession(session_id));
}
} // namespace wvcdm