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:
Rahul Frias
2013-08-15 11:36:20 -07:00
parent f6c2a60485
commit a2e15186e5
12 changed files with 290 additions and 222 deletions

View File

@@ -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());

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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_; }