Add Privacy Mode and Serivce Certificate Support
This merges the following changes from the Widevine CDM repository:
da001b6 Add Privacy mode and service certificate
This adds support to the CDM for privacy mode and service certificates.
92bf200 Add support for using Youtube Content Protection server for testing
Enables testing with Youtube Content Protection server. Google Play license
server is still the default. Select YTCP server by using the flag -icp
e.g. adb shell '/system/bin/request_license_test -icp'
85dcd60 Fixes to enable privacy mode
These includes changes to use PKCS7 padding, corrected root CA formatting
and changes to integration test. Also refactored service certificate
handling.
989971c Correction to request license test
Corrected PropertySetTest to provision when needed. Also added disabled
privacy tests to run against YTCP staging server until GooglePlay
integration is complete.
Bug: 10109249
Change-Id: If81d68c65d743d77a485406f48d1be41a74de0af
This commit is contained in:
@@ -231,7 +231,7 @@ int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
wvcdm::InitLogging(argc, argv);
|
||||
|
||||
wvcdm::ConfigTestEnv config;
|
||||
wvcdm::ConfigTestEnv config(wvcdm::kGooglePlayServer);
|
||||
g_client_auth.assign(config.client_auth());
|
||||
g_key_system.assign(config.key_system());
|
||||
g_wrong_key_id.assign(config.wrong_key_id());
|
||||
|
||||
@@ -3,59 +3,43 @@
|
||||
#include "config_test_env.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// choice of YT, GP, GP_Huahui, SDK_Hali
|
||||
#define USE_SERVER_YT 1
|
||||
#define USE_SERVER_GP 2
|
||||
#define USE_SERVER_SDK_Hali 3
|
||||
|
||||
// select which server to use for testing
|
||||
#define USE_SERVER USE_SERVER_GP
|
||||
|
||||
#if (USE_SERVER == USE_SERVER_SDK_Hali)
|
||||
|
||||
static const std::string kLicenseServer =
|
||||
"http://hamid.kir.corp.google.com:8888/drm";
|
||||
static const std::string kClientAuth = "";
|
||||
static const std::string kKeyId =
|
||||
// Youtube Content Protection license server data
|
||||
const std::string kYtCpLicenseServer =
|
||||
"http://kir03wwwg185.widevine.net/drm";
|
||||
const std::string kYtCpClientAuth = "";
|
||||
const std::string kYtCpKeyId =
|
||||
"000000347073736800000000" // blob size and pssh
|
||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000014" // Widevine system id
|
||||
"0801121030313233343536373839616263646566"; // key - for gHali
|
||||
"0801121030313233343536373839616263646566"; // pssh data
|
||||
|
||||
#elif (USE_SERVER == USE_SERVER_YT)
|
||||
|
||||
static const std::string kLicenseServer =
|
||||
// Youtube license server data
|
||||
const std::string kYtLicenseServer =
|
||||
"https://www.youtube.com/api/drm/"
|
||||
"widevine?video_id=03681262dc412c06&source=YOUTUBE";
|
||||
static const std::string kClientAuth = "";
|
||||
static const std::string kKeyId =
|
||||
const std::string kYtClientAuth = "";
|
||||
const std::string kYtKeyId =
|
||||
"000000347073736800000000" // blob size and pssh
|
||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000014" // Widevine system id
|
||||
"0801121093789920E8D6520098577DF8F2DD5546"; // pssh data
|
||||
|
||||
#elif (USE_SERVER == USE_SERVER_GP)
|
||||
|
||||
static const std::string kLicenseServer =
|
||||
// Google Play license server data
|
||||
const std::string kGpLicenseServer =
|
||||
"https://jmt17.google.com/video-dev/license/GetCencLicense";
|
||||
|
||||
// NOTE: Append a userdata attribute to place a unique marker that the
|
||||
// server team can use to track down specific requests during debugging
|
||||
// e.g., "<existing-client-auth-string>&userdata=<your-ldap>.<your-tag>"
|
||||
// "<existing-client-auth-string>&userdata=jbmr2.dev"
|
||||
static const std::string kClientAuth =
|
||||
const std::string kGpClientAuth =
|
||||
"?source=YOUTUBE&video_id=EGHC6OHNbOo&oauth=ya.gtsqawidevine";
|
||||
|
||||
static const std::string kKeyId =
|
||||
const std::string kGpKeyId =
|
||||
"000000347073736800000000" // blob size and pssh
|
||||
"edef8ba979d64acea3c827dcd51d21ed00000014" // Widevine system id
|
||||
"08011210e02562e04cd55351b14b3d748d36ed8e"; // pssh data
|
||||
|
||||
#else
|
||||
#error "Must define USE_SERVER"
|
||||
#endif
|
||||
|
||||
// An invalid key id, expected to fail
|
||||
static const std::string kWrongKeyId =
|
||||
const std::string kWrongKeyId =
|
||||
"000000347073736800000000" // blob size and pssh
|
||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000014" // Widevine system id
|
||||
"0901121094889920E8D6520098577DF8F2DD5546"; // pssh data
|
||||
@@ -75,19 +59,28 @@ const std::string kProductionTestProvisioningServerUrl =
|
||||
|
||||
const std::string kServerSdkLicenseServer =
|
||||
"http://kir03fcpg174.widevine.net/widevine/cgi-bin/drm.cgi";
|
||||
|
||||
const wvcdm::ConfigTestEnv::LicenseServerConfiguration license_servers[] = {
|
||||
{ wvcdm::kGooglePlayServer, kGpLicenseServer, kGpClientAuth, kGpKeyId,
|
||||
kDefaultHttpsPort, true, true },
|
||||
{ wvcdm::kYouTubeContentProtectionServer, kYtCpLicenseServer,
|
||||
kYtCpClientAuth, kYtCpKeyId, kDefaultHttpPort, false, false }
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
ConfigTestEnv::ConfigTestEnv()
|
||||
: client_auth_(kClientAuth),
|
||||
key_id_(kKeyId),
|
||||
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id)
|
||||
: client_auth_(license_servers[server_id].client_tag),
|
||||
key_id_(license_servers[server_id].key_id),
|
||||
key_system_("com.widevine.alpha"),
|
||||
license_server_(kLicenseServer),
|
||||
port_(kDefaultHttpsPort),
|
||||
license_server_(license_servers[server_id].url),
|
||||
port_(license_servers[server_id].port),
|
||||
provisioning_server_url_(kProductionProvisioningServerUrl),
|
||||
provisioning_test_server_url_(kProductionTestProvisioningServerUrl),
|
||||
server_sdk_license_server_(kServerSdkLicenseServer),
|
||||
use_chunked_transfer_(license_servers[server_id].use_chunked_transfer),
|
||||
use_secure_transfer_(license_servers[server_id].use_secure_transfer),
|
||||
wrong_key_id_(kWrongKeyId) {}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -8,14 +8,29 @@
|
||||
|
||||
namespace {
|
||||
const std::string kDefaultHttpsPort = "443";
|
||||
const std::string kDefaultHttpPort = "80";
|
||||
}
|
||||
|
||||
namespace wvcdm {
|
||||
typedef enum {
|
||||
kGooglePlayServer,
|
||||
kYouTubeContentProtectionServer
|
||||
} LicenseServerId;
|
||||
|
||||
// Configures default test environment.
|
||||
class ConfigTestEnv {
|
||||
public:
|
||||
ConfigTestEnv();
|
||||
typedef struct {
|
||||
LicenseServerId id;
|
||||
std::string url;
|
||||
std::string client_tag;
|
||||
std::string key_id;
|
||||
std::string port;
|
||||
bool use_chunked_transfer;
|
||||
bool use_secure_transfer;
|
||||
} LicenseServerConfiguration;
|
||||
|
||||
explicit ConfigTestEnv(LicenseServerId server_id);
|
||||
~ConfigTestEnv() {};
|
||||
|
||||
const std::string& client_auth() const { return client_auth_; }
|
||||
@@ -32,6 +47,8 @@ class ConfigTestEnv {
|
||||
const std::string& server_sdk_license_server() const {
|
||||
return server_sdk_license_server_;
|
||||
}
|
||||
bool use_chunked_transfer() { return use_chunked_transfer_; }
|
||||
bool use_secure_transfer() { return use_secure_transfer_; }
|
||||
const KeyId& wrong_key_id() const { return wrong_key_id_; }
|
||||
|
||||
void set_key_id(KeyId& key_id) { key_id_.assign(key_id); }
|
||||
@@ -52,6 +69,8 @@ class ConfigTestEnv {
|
||||
std::string provisioning_server_url_;
|
||||
std::string provisioning_test_server_url_;
|
||||
std::string server_sdk_license_server_;
|
||||
bool use_chunked_transfer_;
|
||||
bool use_secure_transfer_;
|
||||
KeyId wrong_key_id_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(ConfigTestEnv);
|
||||
|
||||
@@ -12,10 +12,10 @@ size_t LicenseRequest::FindHeaderEndPosition(
|
||||
return(response.find(kTwoBlankLines));
|
||||
}
|
||||
|
||||
// Returns drm message in drm_msg.
|
||||
// The drm message is at the end of the response message.
|
||||
// This routine parses the license server's response message and
|
||||
// extracts the drm message from the response header.
|
||||
void LicenseRequest::GetDrmMessage(const std::string& response,
|
||||
std::string& drm_msg) {
|
||||
std::string& drm_msg) {
|
||||
if (response.empty()) {
|
||||
drm_msg.clear();
|
||||
return;
|
||||
|
||||
@@ -22,7 +22,6 @@ UrlRequest::UrlRequest(const std::string& url, const std::string& port,
|
||||
port_.assign(port);
|
||||
}
|
||||
if (socket_.Connect((server_url_).c_str(), port_, true, secure_connection)) {
|
||||
LOGD("connected to %s", socket_.domain_name().c_str());
|
||||
is_connected_ = true;
|
||||
} else {
|
||||
LOGE("failed to connect to %s, port=%s", socket_.domain_name().c_str(),
|
||||
@@ -99,26 +98,6 @@ void UrlRequest::ConcatenateChunkedResponse(const std::string http_response,
|
||||
}
|
||||
}
|
||||
|
||||
void UrlRequest::DumpMessage(const std::string& description,
|
||||
const std::string& message) {
|
||||
if (description.empty()) return;
|
||||
|
||||
LOGD("%s (%d bytes):", description.c_str(), message.size());
|
||||
|
||||
size_t remaining = message.size();
|
||||
size_t portion = 0;
|
||||
size_t start = 0;
|
||||
while (remaining > 0) {
|
||||
// LOGX may not get to empty its buffer if it is too large,
|
||||
// pick an arbitrary small size to be safe
|
||||
portion = (remaining < 512) ? remaining : 512;
|
||||
LOGD("%s", message.substr(start, portion).c_str());
|
||||
start += portion;
|
||||
remaining -= portion;
|
||||
}
|
||||
LOGD("total bytes dumped(%d)", start);
|
||||
}
|
||||
|
||||
int UrlRequest::GetResponse(std::string* message) {
|
||||
message->clear();
|
||||
|
||||
@@ -137,7 +116,7 @@ int UrlRequest::GetResponse(std::string* message) {
|
||||
} while (bytes > 0);
|
||||
|
||||
ConcatenateChunkedResponse(response, message);
|
||||
LOGD("%d bytes returned", message->size());
|
||||
LOGD("HTTP response: (%d): %s", message->size(), b2a_hex(*message).c_str());
|
||||
return message->size();
|
||||
}
|
||||
|
||||
@@ -202,6 +181,8 @@ bool UrlRequest::PostRequest(const std::string& data) {
|
||||
request_.append("\r\n\r\n");
|
||||
|
||||
socket_.Write(request_.c_str(), request_.size());
|
||||
LOGD("HTTP request: (%d): %s", request_.size(), request_.c_str());
|
||||
LOGD("HTTP request: (%d): %s", request_.size(), b2a_hex(request_).c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -221,6 +202,8 @@ bool UrlRequest::PostCertRequestInQueryString(const std::string& data) {
|
||||
request_.append("\r\n"); // terminates the request
|
||||
|
||||
socket_.Write(request_.c_str(), request_.size());
|
||||
LOGD("HTTP request: (%d): %s", request_.size(), request_.c_str());
|
||||
LOGD("HTTP request: (%d): %s", request_.size(), b2a_hex(request_).c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ class UrlRequest {
|
||||
void AppendChunkToUpload(const std::string& data);
|
||||
void ConcatenateChunkedResponse(const std::string http_response,
|
||||
std::string* modified_response);
|
||||
void DumpMessage(const std::string& description, const std::string& message);
|
||||
int GetResponse(std::string* message);
|
||||
int GetStatusCode(const std::string& response);
|
||||
bool is_connected() const { return is_connected_; }
|
||||
|
||||
Reference in New Issue
Block a user