CAS Proxy SDK git checkin as per g3doc.

Adds support for specifying service type when creating a service certificate.

A recent change to the SDK allows for service certificates (DrmCertificate) to also specify a ServiceType indicating which type of service they are supposed to be used on.  This CL adds certificate creation service support for this.

-------------
Fix typo in cas proxy SDK.

-------------
Migrate C++ proto_library rules to cc_proto_library.

We update dependency edges of cc_* rules on proto_library() rules to use a cc_proto_library() intermediary in preparation for eliminating proto_library()'s cc support as per []

More information: []

Tested:
    TAP --sample for global presubmit queue
    []

-------------
Migrate cc proto_library to cc_proto_library. Also fixes build break introduced by []

-------------
Remove unnecessary #MOE directives

-------------
[Proxy_SDK] Move generateSignature in WvPLSDKEnvironment to signature_util.cc file.

-------------
[SDK]Add service_certificate type check in WVPL LSDK and PROXY SDK.

-------------
[Proxy_SDK] Add new API to get remote_attestation_cert_serial_number for proxy SDK.

-------------
[Proxy_SDK] Add getDrmDeviceId function

-------------
[Proxy_SDK] add getrequesttype function for proxy sdk

-------------
[SDK] Add videoFeature field to WvPLWidevinePsshData in WvPLWidevine.java and wvpl_type.h. Related to []

-------------
Allow specified devices to request licenses even if these devices are in TEST_ONLY state.
This will also override the global setting of TEST_ONLY devices not being allowed to
successfully receive licenses from Widevine License SDK.

-------------
[Proxy_SDK] Add ParseDCSL function and test case.

-------------
[Proxy_SDK] Return non-ok status for service_certificate_request when create proxy sdk session. Add test case in Java test.

-------------
[Proxy_SDK] Add video_feature parsing in GetPsshData function. Also check video_feature when geneateModularDrmLicenseRequest.

-------------
[SDK]Deprecated message_type() function, use request_type() instead.

-------------
Use JDK instead of JRE

The concept of a JRE is going away in JDK 11. The jre/ subdirectory in the JDK will no longer exist and the :jre targets will no longer make sense.

Currently in JDK 8, the JDK is a superset of the JRE (it contains all of the files in the JRE), so this is a safe change.

Tested:
    TAP found no affected targets
    []

-------------
Renaming WvPLSDKSession.request_type() API.
Added LICENSE_TYPE_UNSPECIFIED enumeration to WvPLLicenseType.

-------------
Additional VLOG messaging for licensing with TEST_ONLY devices.

-------------
Remove forward declarations of absl names. The style guide bans this, and those names are not for external users to redeclare. External users should include the public headers instead.

-------------
Change Kokoro to use latest bazel version

-------------
Update the abseil build to the December 18 release.

This fixes a problem where the MOE build is failing because there was no definition for node_hash_map.

-------------
[CAS_Proxy]Add WvPLCASProxyEnvironmentJNI.cc and com_google_video_widevine_sdk_wvpl_WvPLCASProxyEnvironment.h file to implement JNI layer for WvPLCASProxyEnvironment.

-------------
Apply changes to sdk to match device certificate status list updates.

Cleans up some of the protos we're using for the new SignedDeviceInfo. Also, adjusts the sdk implementation to reflect the proto and service changes.

-------------
[CAS_PROXY]Add WvPLCASProxyEnvironment.java, WvPLCASProxySession.java and WvPLCASProxyTest.java file.

-------------
Add API to return the DRM service certificate by provider.

-------------
[CAS_PROXY]Implement SetDrmServiceCertificate and SetDeviceCertificateStatusList JNI layer.

-------------
Get DeviceInfo from request.

-------------
CAS Proxy SDK updated to 1.1.5.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=248640225
This commit is contained in:
Ramji Chandramouli
2019-05-16 18:14:58 -07:00
parent 74b7f405c8
commit be0bb27305
44 changed files with 1496 additions and 577 deletions

View File

@@ -73,11 +73,11 @@ cc_library(
"@abseil_repo//absl/synchronization",
"@abseil_repo//absl/time",
"//util/gtl:map_util",
"//protos/public:client_identification_proto",
"//protos/public:drm_certificate_proto",
"//protos/public:errors_proto",
"//protos/public:license_protocol_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:client_identification_cc_proto",
"//protos/public:drm_certificate_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:license_protocol_cc_proto",
"//protos/public:signed_drm_certificate_cc_proto",
],
)
@@ -99,9 +99,9 @@ cc_test(
"@abseil_repo//absl/time",
"//common:rsa_key",
"//common:rsa_test_keys",
"//protos/public:drm_certificate_proto",
"//protos/public:errors_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:drm_certificate_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:signed_drm_certificate_cc_proto",
],
)
@@ -111,22 +111,19 @@ cc_library(
hdrs = ["device_status_list.h"],
deps = [
":client_cert",
":crypto_util",
":drm_root_certificate",
":drm_service_certificate",
":error_space",
":random_util",
":rsa_key",
":signing_key_util",
":status",
"//base",
"@abseil_repo//absl/strings",
"@abseil_repo//absl/synchronization",
"//util/gtl:map_util",
"//protos/public:client_identification_proto",
"//protos/public:device_certificate_status_proto",
"//protos/public:errors_proto",
"//protos/public:provisioned_device_info_proto",
"//protos/public:client_identification_cc_proto",
"//protos/public:device_certificate_status_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:provisioned_device_info_cc_proto",
"//protos/public:signed_device_info_cc_proto",
],
)
@@ -137,15 +134,17 @@ cc_test(
deps = [
":client_cert",
":device_status_list",
":rsa_key",
":rsa_test_keys",
":status",
"//base",
"//testing:gunit_main",
"@abseil_repo//absl/strings",
"//common:rsa_key",
"//common:rsa_test_keys",
"//protos/public:client_identification_proto",
"//protos/public:errors_proto",
"//protos/public:provisioned_device_info_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:client_identification_cc_proto",
"//protos/public:device_certificate_status_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:provisioned_device_info_cc_proto",
"//protos/public:signed_drm_certificate_cc_proto",
],
)
@@ -164,9 +163,9 @@ cc_library(
"@abseil_repo//absl/strings",
"@abseil_repo//absl/synchronization",
"//external:openssl",
"//protos/public:drm_certificate_proto",
"//protos/public:errors_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:drm_certificate_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:signed_drm_certificate_cc_proto",
],
)
@@ -183,9 +182,9 @@ cc_test(
"//base",
"//external:protobuf",
"//testing:gunit_main",
"//protos/public:drm_certificate_proto",
"//protos/public:errors_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:drm_certificate_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:signed_drm_certificate_cc_proto",
],
)
@@ -200,8 +199,8 @@ cc_library(
":status",
"//base",
"@abseil_repo//absl/strings",
"//protos/public:client_identification_proto",
"//protos/public:errors_proto",
"//protos/public:client_identification_cc_proto",
"//protos/public:errors_cc_proto",
],
)
@@ -431,7 +430,7 @@ cc_library(
deps = [
":crypto_util",
"//base",
"//protos/public:license_protocol_proto",
"//protos/public:license_protocol_cc_proto",
],
)
@@ -445,7 +444,7 @@ cc_test(
"//testing:gunit",
"//testing:gunit_main",
"@abseil_repo//absl/strings",
"//protos/public:license_protocol_proto",
"//protos/public:license_protocol_cc_proto",
],
)
@@ -509,7 +508,7 @@ cc_library(
deps = [
"//util:error_space",
"//util:proto_status",
"//protos/public:errors_proto",
"//protos/public:errors_cc_proto",
],
)
@@ -527,9 +526,9 @@ cc_library(
"//base",
"@abseil_repo//absl/strings",
"@abseil_repo//absl/synchronization",
"//protos/public:client_identification_proto",
"//protos/public:errors_proto",
"//protos/public:remote_attestation_proto",
"//protos/public:client_identification_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:remote_attestation_cc_proto",
],
)
@@ -549,10 +548,10 @@ cc_library(
"@abseil_repo//absl/strings",
"@abseil_repo//absl/synchronization",
"//util/gtl:map_util",
"//protos/public:client_identification_proto",
"//protos/public:drm_certificate_proto",
"//protos/public:errors_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:client_identification_cc_proto",
"//protos/public:drm_certificate_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:signed_drm_certificate_cc_proto",
],
)
@@ -572,11 +571,11 @@ cc_test(
"//external:protobuf",
"//testing:gunit_main",
"@abseil_repo//absl/strings",
"//protos/public:client_identification_proto",
"//protos/public:drm_certificate_proto",
"//protos/public:errors_proto",
"//protos/public:license_server_sdk_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:client_identification_cc_proto",
"//protos/public:drm_certificate_cc_proto",
"//protos/public:errors_cc_proto",
"//protos/public:license_server_sdk_cc_proto",
"//protos/public:signed_drm_certificate_cc_proto",
],
)
@@ -589,7 +588,7 @@ cc_library(
":vmp_checker",
"//base",
"@abseil_repo//absl/strings",
"//protos/public:license_protocol_proto",
"//protos/public:license_protocol_cc_proto",
],
)
@@ -646,8 +645,8 @@ cc_library(
":status",
":x509_cert",
"//base",
"//protos/public:errors_proto",
"//protos/public:verified_media_pipeline_proto",
"//protos/public:errors_cc_proto",
"//protos/public:verified_media_pipeline_cc_proto",
],
)
@@ -661,8 +660,8 @@ cc_test(
"//base",
"//testing:gunit_main",
"@abseil_repo//absl/strings",
"//protos/public:errors_proto",
"//protos/public:verified_media_pipeline_proto",
"//protos/public:errors_cc_proto",
"//protos/public:verified_media_pipeline_cc_proto",
],
)

View File

@@ -11,6 +11,7 @@
#include "common/device_status_list.h"
#include <time.h>
#include <memory>
#include "glog/logging.h"
@@ -24,8 +25,13 @@
#include "common/drm_service_certificate.h"
#include "common/error_space.h"
#include "common/rsa_key.h"
#include "common/status.h"
#include "protos/public/client_identification.pb.h"
#include "protos/public/errors.pb.h"
#include "protos/public/signed_device_info.pb.h"
using ::widevine::DeviceCertificateStatusListRequest;
using ::widevine::SignedDeviceInfoRequest;
namespace widevine {
@@ -54,19 +60,13 @@ DeviceStatusList::~DeviceStatusList() {}
Status DeviceStatusList::UpdateStatusList(
const std::string& root_certificate_public_key,
const std::string& serialized_certificate_status_list,
uint32_t expiration_period_seconds) {
SignedDeviceCertificateStatusList signed_certificate_status_list;
if (!signed_certificate_status_list.ParseFromString(
serialized_certificate_status_list)) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"signed-certificate-status-list-parse-error");
}
if (!signed_certificate_status_list.has_certificate_status_list()) {
const std::string& serialized_device_certificate_status_list,
const std::string& signature, uint32_t expiration_period_seconds) {
if (serialized_device_certificate_status_list.empty()) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"missing-status-list");
}
if (!signed_certificate_status_list.has_signature()) {
if (signature.empty()) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"missing-status-list-signature");
}
@@ -76,17 +76,16 @@ Status DeviceStatusList::UpdateStatusList(
return Status(error_space, INVALID_DRM_CERTIFICATE,
"invalid-root-public-key");
}
if (!root_key->VerifySignature(
signed_certificate_status_list.certificate_status_list(),
signed_certificate_status_list.signature())) {
if (!root_key->VerifySignature(serialized_device_certificate_status_list,
signature)) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"invalid-status-list-signature");
}
DeviceCertificateStatusList certificate_status_list;
if (!certificate_status_list.ParseFromString(
signed_certificate_status_list.certificate_status_list())) {
serialized_device_certificate_status_list)) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"certificate-status-list-parse-error");
"signed-certificate-status-list-parse-error");
}
if (expiration_period_seconds &&
(GetCurrentTime() > (certificate_status_list.creation_time_seconds() +
@@ -162,8 +161,16 @@ Status DeviceStatusList::GetCertStatus(const ClientCert& client_cert,
if ((device_cert_status->status() ==
DeviceCertificateStatus::STATUS_TEST_ONLY) &&
!allow_test_only_devices_) {
return Status(error_space, DEVELOPMENT_CERTIFICATE_NOT_ALLOWED,
"test-only-drm-certificate-not-allowed");
if (IsTestOnlyDeviceAllowed(client_cert.system_id(),
device_info->manufacturer())) {
LOG(WARNING) << "Allowing TEST_ONLY device: "
<< device_info->ShortDebugString();
} else {
VLOG(2) << "TEST ONLY device with systemId: " << client_cert.system_id()
<< " not allowed";
return Status(error_space, DEVELOPMENT_CERTIFICATE_NOT_ALLOWED,
"test-only-drm-certificate-not-allowed");
}
}
if (!client_cert.signed_by_provisioner() &&
(client_cert.signer_serial_number() !=
@@ -241,31 +248,83 @@ void DeviceStatusList::AllowRevokedDevices(const std::string& system_id_list) {
std::sort(allowed_revoked_devices_.begin(), allowed_revoked_devices_.end());
}
void DeviceStatusList::AllowTestOnlyDevices(const std::string& device_list) {
absl::WriterMutexLock lock(&allowed_test_only_devices_mutex_);
// 'device_list' is expected to be of the format <device>,<device>..., and
// each 'device' will contain a 'system_id' and 'manufacturer' OR will contain
// only a 'system_id'.
for (absl::string_view device : absl::StrSplit(device_list, ',')) {
// 'device' is expected to be of the format <system_id>:<manufacturer> OR
// of the format <system_id>:
const std::pair<absl::string_view, absl::string_view> device_split =
absl::StrSplit(device, ':');
if (device_split.second.empty()) {
allowed_test_only_devices_[std::stoi(std::string(device_split.first))] = "*";
} else {
allowed_test_only_devices_[std::stoi(std::string(device_split.first))] =
std::string(device_split.second);
}
VLOG(2)
<< "Whitelisting TEST_ONLY device: systemId = "
<< std::stoi(std::string(device_split.first))
<< allowed_test_only_devices_[std::stoi(std::string(device_split.first))];
}
}
bool DeviceStatusList::IsRevokedSystemIdAllowed(uint32_t system_id) {
auto it = std::binary_search(allowed_revoked_devices_.begin(),
allowed_revoked_devices_.end(), system_id);
return it;
}
Status DeviceStatusList::ExtractFromProvisioningServiceResponse(
const std::string& certificate_provisioning_service_response,
std::string* signed_certificate_status_list, std::string* certificate_status_list) {
Status status = OkStatus();
size_t signed_list_start =
certificate_provisioning_service_response.find(kSignedList);
if (signed_list_start != std::string::npos) {
size_t signed_list_end = certificate_provisioning_service_response.find(
kSignedListTerminator, signed_list_start);
if (signed_list_end == std::string::npos) {
bool DeviceStatusList::IsTestOnlyDeviceAllowed(uint32_t system_id,
std::string manufacturer) {
absl::ReaderMutexLock lock(&allowed_test_only_devices_mutex_);
std::string* allowed_manufacturer =
gtl::FindOrNull(allowed_test_only_devices_, system_id);
if (allowed_manufacturer == nullptr) {
return false;
}
if (*allowed_manufacturer == "*" || *allowed_manufacturer == manufacturer) {
return true;
}
return false;
}
Status DeviceStatusList::ExtractFromServiceResponse(
const std::string& service_response, std::string* serialized_certificate_status_list,
std::string* signature) {
// We support two types of payload parsing. First, is the legacy call which
// is a serialized SignedCertificateStatusList proto. The second is the
// newer SignedDeviceInfo.
// TODO(user): Add support for the new response type.
return ExtractLegacyDeviceList(service_response,
serialized_certificate_status_list, signature);
}
Status DeviceStatusList::ExtractLegacyDeviceList(
const std::string& raw_certificate_provisioning_service_response,
std::string* serialized_certificate_status_list, std::string* signature) {
// Example legacy format.
// "signedList":"<b64 encoded data>"
// where the b64 encoded data is a DeviceCertificateStatusListResponse.
size_t b64_list_response_start =
raw_certificate_provisioning_service_response.find(kSignedList);
std::string serialized_certificate_status_list_response;
if (b64_list_response_start != std::string::npos) {
size_t b64_list_response_end =
raw_certificate_provisioning_service_response.find(
kSignedListTerminator, b64_list_response_start);
if (b64_list_response_end == std::string::npos) {
return Status(
error_space, error::INVALID_ARGUMENT,
"Unable to parse the certificate_provisioning_service_response. "
"SignedList not terminated.");
}
std::string signed_list(
certificate_provisioning_service_response.begin() + signed_list_start +
kSignedListLen,
certificate_provisioning_service_response.begin() + signed_list_end);
std::string signed_list(raw_certificate_provisioning_service_response.begin() +
b64_list_response_start + kSignedListLen,
raw_certificate_provisioning_service_response.begin() +
b64_list_response_end);
// Strip off quotes.
signed_list.erase(std::remove(signed_list.begin(), signed_list.end(), '\"'),
@@ -281,9 +340,10 @@ Status DeviceStatusList::ExtractFromProvisioningServiceResponse(
// Strip off carriage return (the control-M character)
signed_list.erase(std::remove(signed_list.begin(), signed_list.end(), '\r'),
signed_list.end());
if (!absl::WebSafeBase64Unescape(signed_list,
signed_certificate_status_list)) {
if (!absl::Base64Unescape(signed_list, signed_certificate_status_list)) {
if (!absl::WebSafeBase64Unescape(
signed_list, &serialized_certificate_status_list_response)) {
if (!absl::Base64Unescape(signed_list,
&serialized_certificate_status_list_response)) {
return Status(error_space, error::INVALID_ARGUMENT,
"Base64 decode of signedlist failed.");
}
@@ -291,36 +351,32 @@ Status DeviceStatusList::ExtractFromProvisioningServiceResponse(
} else {
// certificate_provisioning_service_response is the signed list and not a
// JSON message.
if (!absl::WebSafeBase64Unescape(certificate_provisioning_service_response,
signed_certificate_status_list)) {
if (!absl::Base64Unescape(certificate_provisioning_service_response,
signed_certificate_status_list)) {
if (!absl::WebSafeBase64Unescape(
raw_certificate_provisioning_service_response,
&serialized_certificate_status_list_response)) {
if (!absl::Base64Unescape(raw_certificate_provisioning_service_response,
&serialized_certificate_status_list_response)) {
return Status(error_space, error::INVALID_ARGUMENT,
"Base64 decode of certList failed.");
}
}
}
SignedDeviceCertificateStatusList signed_status_list;
if (!signed_status_list.ParseFromString(*signed_certificate_status_list)) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"signed-certificate-status-list-parse-error");
}
if (!signed_status_list.has_certificate_status_list()) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"missing-status-list");
}
DeviceCertificateStatusList device_certificate_status_list;
if (!device_certificate_status_list.ParseFromString(
signed_status_list.certificate_status_list())) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"certificate-status-list-parse-error");
}
*certificate_status_list = signed_status_list.certificate_status_list();
return OkStatus();
return ParseSignedDeviceCertificateStatusList(
serialized_certificate_status_list_response,
serialized_certificate_status_list, signature);
}
Status DeviceStatusList::ExtractSignedDeviceInfo(
const std::string& signed_device_info_response,
std::string* serialized_certificate_status_list, std::string* signature) {
// TODO(user): Implement this.
return Status(error_space, error::UNIMPLEMENTED,
"SignedDeviceInfo not yet supported.");
}
Status DeviceStatusList::GenerateSignedDeviceCertificateStatusListRequest(
const std::string& version,
const std::string& version, const std::string& serialized_service_certificate,
std::string* signed_device_certificate_status_list_request) {
if (version.empty()) {
return Status(error_space, error::INVALID_ARGUMENT, "SDK version is empty");
@@ -334,9 +390,10 @@ Status DeviceStatusList::GenerateSignedDeviceCertificateStatusListRequest(
DeviceCertificateStatusListRequest request;
request.set_sdk_version(version);
request.set_sdk_time_seconds(DeviceStatusList::Instance()->GetCurrentTime());
request.set_service_certificate(serialized_service_certificate);
std::string device_certificate_status_list_request;
request.SerializeToString(&device_certificate_status_list_request);
SignedDeviceCertificateStatusListRequest signed_request;
SignedDeviceInfoRequest signed_request;
signed_request.set_device_certificate_status_list_request(
device_certificate_status_list_request);
const DrmServiceCertificate* sc =
@@ -359,4 +416,34 @@ Status DeviceStatusList::GenerateSignedDeviceCertificateStatusListRequest(
signed_device_certificate_status_list_request);
return OkStatus();
}
Status DeviceStatusList::ParseSignedDeviceCertificateStatusList(
const std::string& serialized_signed_device_certificate_status_list,
std::string* serialized_device_certificate_status_list, std::string* signature) {
// Parse the serialized signed device info to extract the certificate
// status list.
SignedDeviceCertificateStatusList signed_device_list;
if (!signed_device_list.ParseFromString(
serialized_signed_device_certificate_status_list)) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"signed-certificate-status-list-parse-error");
}
if (signed_device_list.certificate_status_list().empty()) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"missing-status-list");
}
// Parse the DCSL to verify that it's a properly serialized protobuf.
DeviceCertificateStatusList certificate_status_list;
if (!certificate_status_list.ParseFromString(
signed_device_list.certificate_status_list())) {
return Status(error_space, INVALID_CERTIFICATE_STATUS_LIST,
"certificate-status-list-parse-error");
}
// TODO(user): See if we can refactor this. It seems weird to deserialize
// the proto but then pass around the serialized proto.
*serialized_device_certificate_status_list =
signed_device_list.certificate_status_list();
*signature = signed_device_list.signature();
return OkStatus();
}
} // namespace widevine

View File

@@ -19,6 +19,7 @@
#include "common/status.h"
#include "protos/public/device_certificate_status.pb.h"
#include "protos/public/provisioned_device_info.pb.h"
#include "protos/public/signed_device_info.pb.h"
namespace widevine {
@@ -37,12 +38,14 @@ class DeviceStatusList {
DeviceStatusList();
virtual ~DeviceStatusList();
// Takes |serialized_certificate_status_list| and copies to an internal map of
// device certifcate status list. The internal map is used to verify
// a device was not revoked. Returns true is the list was successfully parsed.
Status UpdateStatusList(const std::string& root_certificate_public_key,
const std::string& serialized_certificate_status_list,
uint32_t expiration_period_seconds);
// Takes |serialized_device_certificate_status_list| and copies to an
// internal map of device certificate status list. The internal map is used
// to verify a device was not revoked. Returns true is the list was
// successfully parsed.
Status UpdateStatusList(
const std::string& root_certificate_public_key,
const std::string& serialized_device_certificate_status_list,
const std::string& signature, uint32_t expiration_period_seconds);
void set_allow_unknown_devices(bool flag) { allow_unknown_devices_ = flag; }
bool allow_unknown_devices() const { return allow_unknown_devices_; }
void set_allow_test_only_devices(bool allow) {
@@ -76,18 +79,28 @@ class DeviceStatusList {
// a comma separated list of systems Ids to allow even if revoked.
virtual void AllowRevokedDevices(const std::string& system_id_list);
// Enable delivery of licenses to TEST_ONLY client devices. |device_list| is
// a comma separated list of devices to allow even if the device state is
// TEST_ONLY. Each device is specified by a colon separated system_id and
// manufacturer. If the manufacturer is not specified, all manufacturers for
// that system_id are allowed.
virtual void AllowTestOnlyDevices(const std::string& device_list);
/**
* Parses signed device certificate status list and certificate status list
* from certificateProvisoningServer response.
* Parses the serialized certificate status list and the signature from the
* service_response. The service_response is the JSON payload that comes
* in the response to a certificate status list request. Both the legacy
* format and the newer SignedDeviceInfo format are supported.
*
* @param certificate_provisioning_service_response
* @param signed_certificate_status_list
* @param certificate_status_list
* @param service_response
* @param serialized_certificate_status_list
* @param signature
* @return WvPLStatus - Status::OK if success, else error.
*/
static Status ExtractFromProvisioningServiceResponse(
const std::string& certificate_provisioning_service_response,
std::string* signed_certificate_status_list, std::string* certificate_status_list);
static Status ExtractFromServiceResponse(
const std::string& service_response,
std::string* serialized_certificate_status_list, std::string* signature);
/**
* Constructs signed device certificate status list request string.
*
@@ -96,13 +109,60 @@ class DeviceStatusList {
* @return Status - Status::OK if success, else error.
*/
static Status GenerateSignedDeviceCertificateStatusListRequest(
const std::string& version,
const std::string& version, const std::string& serialized_service_certificate,
std::string* signed_device_certificate_status_list_request);
private:
friend class DeviceStatusListTest;
/**
* Parses the serialized legacy device certificate status list and signature.
* The certificate_provisioning_service_response is the JSON payload that
* comes in the response to a certificate status list request.
*
* @param legacy_certificate_provisioning_service_response
* @param serialized_certificate_status_list
* @param signature
* @return WvPLStatus - Status::OK if success, else error.
*/
static Status ExtractLegacyDeviceList(
const std::string& raw_certificate_provisioning_service_response,
std::string* serialized_certificate_status_list, std::string* signature);
/**
* Parses the serialized signed device info response.
* The signed_device_info_response is the JSON payload that comes in the
* response to a signed device info request.
*
* @param legacy_certificate_provisioning_service_response
* @param serialized_certificate_status_list
* @param signature
* @return WvPLStatus - Status::OK if success, else error.
*/
static Status ExtractSignedDeviceInfo(
const std::string& signed_device_info_response,
std::string* serialized_certificate_status_list, std::string* signature);
/**
* Returns a |serialized_device_certificate_status_list| in its output
* parameter by parsing |serialized_signed_device_certificate_status_list|
* returned from Widevine Certificate Provisioning Server.
*
* @param serialized_signed_device_certificate_status_list
* @param serialized_device_certificate_status_list
*
* @return Status - Status::OK if success, else error.
*/
static Status ParseSignedDeviceCertificateStatusList(
const std::string& serialized_signed_device_certificate_status_list,
std::string* serialized_device_certificate_status_list, std::string* signature);
// Returns true if the system ID is allowed to be revoked.
// Caller owns |system_id|. They must not be null.
bool IsRevokedSystemIdAllowed(uint32_t system_id);
// Returns true if the device, which is identified by system_id and
// manufacturer, is present in |allowed_test_only_devices_|.
bool IsTestOnlyDeviceAllowed(uint32_t system_id, std::string manufacturer);
absl::Mutex status_map_lock_;
// Key is the system id for the device.
@@ -114,6 +174,12 @@ class DeviceStatusList {
// Contains the list of system_id values that are allowed to succeed even if
// revoked.
std::vector<uint32_t> allowed_revoked_devices_;
absl::Mutex allowed_test_only_devices_mutex_;
// Contains a map of TEST_ONLY devices that are allowed, even if TEST_ONLY
// devices are prohibited. Contains mappings of 'system_id' to
// 'manufacturer'. If 'manufacturer' value is "*", any 'manufacturer' for
// that 'system_id' is allowed.
std::map<uint32_t, std::string> allowed_test_only_devices_;
DISALLOW_COPY_AND_ASSIGN(DeviceStatusList);
};

View File

@@ -9,6 +9,7 @@
#include "common/device_status_list.h"
#include <stddef.h>
#include <memory>
#include <type_traits>
#include <utility>
@@ -16,15 +17,26 @@
#include "glog/logging.h"
#include "testing/gmock.h"
#include "testing/gunit.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "common/client_cert.h"
#include "common/rsa_key.h"
#include "common/rsa_test_keys.h"
#include "common/status.h"
#include "protos/public/client_identification.pb.h"
#include "protos/public/device_certificate_status.pb.h"
#include "protos/public/errors.pb.h"
#include "protos/public/provisioned_device_info.pb.h"
#include "protos/public/signed_drm_certificate.pb.h"
namespace {
const char kTestSystemId_1[] = "4121";
const char kTestManufacturer_1[] = "LG";
const char kTestSystemId_2[] = "8242";
const char kTestManufacturer_2[] = "Samsung";
const char kTestSystemId_3[] = "6556";
} // namespace
namespace widevine {
using ::testing::_;
@@ -103,26 +115,50 @@ class DeviceStatusListTest : public ::testing::Test {
cert_status_list_.set_creation_time_seconds(kStatusListCreationTime);
cert_status_list_.SerializeToString(
signed_cert_status_list_.mutable_certificate_status_list());
legacy_signed_device_status_list_.mutable_certificate_status_list());
std::unique_ptr<RsaPrivateKey> root_key(
RsaPrivateKey::Create(test_keys_.private_test_key_1_3072_bits()));
ASSERT_TRUE(root_key);
ASSERT_TRUE(root_key->GenerateSignature(
signed_cert_status_list_.certificate_status_list(),
signed_cert_status_list_.mutable_signature()));
ASSERT_TRUE(
signed_cert_status_list_.SerializeToString(&serialized_status_list_));
legacy_signed_device_status_list_.certificate_status_list(),
legacy_signed_device_status_list_.mutable_signature()));
ASSERT_TRUE(legacy_signed_device_status_list_.SerializeToString(
&serialized_status_list_));
ASSERT_EQ(OkStatus(), device_status_list_.UpdateStatusList(
test_keys_.public_test_key_1_3072_bits(),
serialized_status_list_, kDefaultExpirePeriod));
ASSERT_EQ(OkStatus(),
device_status_list_.UpdateStatusList(
test_keys_.public_test_key_1_3072_bits(),
legacy_signed_device_status_list_.certificate_status_list(),
legacy_signed_device_status_list_.signature(),
kDefaultExpirePeriod));
std::string serialized_signed_device_info;
ASSERT_TRUE(legacy_signed_device_status_list_.SerializeToString(
&serialized_signed_device_info));
std::string dcsl;
std::string signature;
ASSERT_EQ(OkStatus(),
DeviceStatusList::ParseSignedDeviceCertificateStatusList(
serialized_signed_device_info, &dcsl, &signature));
ASSERT_EQ(dcsl,
legacy_signed_device_status_list_.certificate_status_list());
ASSERT_EQ(dcsl,
legacy_signed_device_status_list_.certificate_status_list());
}
int VerifyAllowedTestOnlyDevicesAdded() {
return device_status_list_.allowed_test_only_devices_.size();
}
bool VerifyIsTestOnlyDeviceAllowed(uint32_t system_id, std::string manufacturer) {
return device_status_list_.IsTestOnlyDeviceAllowed(system_id, manufacturer);
}
DeviceStatusList device_status_list_;
RsaTestKeys test_keys_;
DeviceCertificateStatusList cert_status_list_;
SignedDeviceCertificateStatusList signed_cert_status_list_;
SignedDeviceInfo tmp_signed_device_info_;
SignedDeviceCertificateStatusList legacy_signed_device_status_list_;
std::string serialized_status_list_;
};
@@ -288,17 +324,19 @@ TEST_F(DeviceStatusListTest, SignerSerialNumberMismatch) {
TEST_F(DeviceStatusListTest, InvalidStatusList) {
EXPECT_EQ(INVALID_CERTIFICATE_STATUS_LIST,
device_status_list_
.UpdateStatusList(test_keys_.public_test_key_2_2048_bits(),
serialized_status_list_, 0)
.UpdateStatusList(
test_keys_.public_test_key_2_2048_bits(),
legacy_signed_device_status_list_.certificate_status_list(),
legacy_signed_device_status_list_.signature(), 0)
.error_code());
++(*signed_cert_status_list_.mutable_certificate_status_list())[4];
ASSERT_TRUE(
signed_cert_status_list_.SerializeToString(&serialized_status_list_));
++(*legacy_signed_device_status_list_.mutable_certificate_status_list())[4];
EXPECT_EQ(INVALID_CERTIFICATE_STATUS_LIST,
device_status_list_
.UpdateStatusList(test_keys_.public_test_key_1_3072_bits(),
serialized_status_list_, 0)
.UpdateStatusList(
test_keys_.public_test_key_1_3072_bits(),
legacy_signed_device_status_list_.certificate_status_list(),
legacy_signed_device_status_list_.signature(), 0)
.error_code());
}
@@ -313,13 +351,17 @@ TEST_F(DeviceStatusListTest, ExpiredStatusListOnSet) {
.Times(2)
.WillOnce(Return(kStatusListCreationTime + 100))
.WillOnce(Return(kStatusListCreationTime + 101));
EXPECT_EQ(OkStatus(), mock_device_status_list.UpdateStatusList(
test_keys_.public_test_key_1_3072_bits(),
serialized_status_list_, 100));
EXPECT_EQ(OkStatus(),
mock_device_status_list.UpdateStatusList(
test_keys_.public_test_key_1_3072_bits(),
legacy_signed_device_status_list_.certificate_status_list(),
legacy_signed_device_status_list_.signature(), 100));
EXPECT_EQ(EXPIRED_CERTIFICATE_STATUS_LIST,
mock_device_status_list
.UpdateStatusList(test_keys_.public_test_key_1_3072_bits(),
serialized_status_list_, 100)
.UpdateStatusList(
test_keys_.public_test_key_1_3072_bits(),
legacy_signed_device_status_list_.certificate_status_list(),
legacy_signed_device_status_list_.signature(), 100)
.error_code());
}
@@ -330,9 +372,11 @@ TEST_F(DeviceStatusListTest, ExpiredStatusListOnCertCheck) {
.WillOnce(Return(kStatusListCreationTime + 100))
.WillOnce(Return(kStatusListCreationTime + 100))
.WillOnce(Return(kStatusListCreationTime + 101));
EXPECT_EQ(OkStatus(), mock_device_status_list.UpdateStatusList(
test_keys_.public_test_key_1_3072_bits(),
serialized_status_list_, 100));
EXPECT_EQ(OkStatus(),
mock_device_status_list.UpdateStatusList(
test_keys_.public_test_key_1_3072_bits(),
legacy_signed_device_status_list_.certificate_status_list(),
legacy_signed_device_status_list_.signature(), 100));
ProvisionedDeviceInfo device_info;
MockCertificateClientCert valid_client_cert;
@@ -373,4 +417,33 @@ TEST_F(DeviceStatusListTest, IsSystemIdActive) {
device_status_list_.IsSystemIdActive(kRevokedAllowedDeviceCertSystemId));
}
TEST_F(DeviceStatusListTest, IsTestOnlyDeviceAllowed) {
std::string device_list =
std::string(kTestSystemId_1) + ":" + std::string(kTestManufacturer_1);
device_list +=
"," + std::string(kTestSystemId_2) + ":" + std::string(kTestManufacturer_2);
device_list += "," + std::string(kTestSystemId_3) + ":";
device_status_list_.AllowTestOnlyDevices(device_list);
EXPECT_EQ(3, VerifyAllowedTestOnlyDevicesAdded());
// Verify that device with system_id = kTestSystemId_1 and
// manufacturer = kTestManufacturer_1 is allowed.
EXPECT_TRUE(VerifyIsTestOnlyDeviceAllowed(std::stoi(kTestSystemId_1),
kTestManufacturer_1));
// Verify that device with system_id = kTestSystemId_2 and
// manufacturer = kTestManufacturer_2 is allowed.
EXPECT_TRUE(VerifyIsTestOnlyDeviceAllowed(std::stoi(kTestSystemId_2),
kTestManufacturer_2));
// Verify that device with system_id = kTestSystemId_3 and
// any manufacturer is allowed. This checks that any manufacturer is
// allowed for this system_id.
EXPECT_TRUE(
VerifyIsTestOnlyDeviceAllowed(std::stoi(kTestSystemId_3), "Cisco"));
EXPECT_TRUE(VerifyIsTestOnlyDeviceAllowed(std::stoi(kTestSystemId_3),
"ScientificAtlanta"));
uint32_t unknown_system_id = 7890;
// Verify that device with system_id = unknown_system_id and
// manufacturer = "Cisco" is not allowed.
EXPECT_FALSE(VerifyIsTestOnlyDeviceAllowed(unknown_system_id, "Cisco"));
}
} // namespace widevine

View File

@@ -80,10 +80,11 @@ TEST(DrmRootCertificateTestCertificatesTest, Success) {
->VerifyCertificate(test_certs.test_user_device_certificate(),
nullptr, nullptr)
.ok());
EXPECT_TRUE(root_cert
->VerifyCertificate(test_certs.test_service_certificate(),
nullptr, nullptr)
.ok());
EXPECT_TRUE(
root_cert
->VerifyCertificate(test_certs.test_service_certificate_no_type(),
nullptr, nullptr)
.ok());
}
class DrmRootCertificateTest : public testing::Test {

View File

@@ -44,8 +44,9 @@ class DrmServiceCertificateMap {
void AddCert(std::unique_ptr<DrmServiceCertificate> new_cert);
void ClearDefaultDrmServiceCertificate();
const DrmServiceCertificate* GetDefaultCert();
const DrmServiceCertificate* GetCert(const std::string& serial_number);
const DrmServiceCertificate* GetCertBySerialNumber(
const std::string& serial_number);
const DrmServiceCertificate* GetCertByProvider(const std::string& provider_id);
static DrmServiceCertificateMap* GetInstance();
private:
@@ -94,12 +95,30 @@ const DrmServiceCertificate* DrmServiceCertificateMap::GetDefaultCert() {
return default_cert_;
}
const DrmServiceCertificate* DrmServiceCertificateMap::GetCert(
const DrmServiceCertificate* DrmServiceCertificateMap::GetCertBySerialNumber(
const std::string& serial_number) {
absl::ReaderMutexLock lock(&mutex_);
return map_[serial_number].get();
}
const DrmServiceCertificate* DrmServiceCertificateMap::GetCertByProvider(
const std::string& provider_id) {
absl::ReaderMutexLock lock(&mutex_);
DrmServiceCertificate* provider_drm_cert = nullptr;
for (const auto& drm_cert : map_) {
if (drm_cert.second->provider_id() == provider_id) {
if (provider_drm_cert == nullptr) {
provider_drm_cert = drm_cert.second.get();
} else if (drm_cert.second->creation_time_seconds() >
provider_drm_cert->creation_time_seconds()) {
// Use the newest cert.
provider_drm_cert = drm_cert.second.get();
}
}
}
return provider_drm_cert;
}
DrmServiceCertificateMap* DrmServiceCertificateMap::GetInstance() {
static auto* const kInstance = new DrmServiceCertificateMap();
return kInstance;
@@ -166,9 +185,17 @@ DrmServiceCertificate::GetDefaultDrmServiceCertificateOrDie() {
return default_cert;
}
const DrmServiceCertificate* DrmServiceCertificate::GetDrmServiceCertificate(
const DrmServiceCertificate*
DrmServiceCertificate::GetDrmServiceCertificateBySerialNumber(
const std::string& serial_number) {
return DrmServiceCertificateMap::GetInstance()->GetCert(serial_number);
return DrmServiceCertificateMap::GetInstance()->GetCertBySerialNumber(
serial_number);
}
const DrmServiceCertificate*
DrmServiceCertificate::GetDrmServiceCertificateByProvider(
const std::string& provider) {
return DrmServiceCertificateMap::GetInstance()->GetCertByProvider(provider);
}
Status DrmServiceCertificate::SetDefaultDrmServiceCertificate(
@@ -207,7 +234,7 @@ Status DrmServiceCertificate::DecryptClientIdentification(
}
std::string privacy_key;
std::string provider_id;
const DrmServiceCertificate* cert = GetDrmServiceCertificate(
const DrmServiceCertificate* cert = GetDrmServiceCertificateBySerialNumber(
encrypted_client_id.service_certificate_serial_number());
if (!cert) {
return Status(

View File

@@ -69,11 +69,17 @@ class DrmServiceCertificate {
// Certificate is set. This method is thread-safe.
static const DrmServiceCertificate* GetDefaultDrmServiceCertificateOrDie();
// Returns the service certificate with the given serial number if found, or
// Returns the service certificate with the given |cert_serial_number|, or
// null otherwise.
static const DrmServiceCertificate* GetDrmServiceCertificate(
static const DrmServiceCertificate* GetDrmServiceCertificateBySerialNumber(
const std::string& cert_serial_number);
// Returns the service certificate with the given |provider_id|, or
// null otherwise. If multple certificates exist for the provider, the
// newest certificate is returned.
static const DrmServiceCertificate* GetDrmServiceCertificateByProvider(
const std::string& provider_id);
// Decrypts the EncryptedClientIdentification message passed in
// |encrypted_client_id| into |client_id| using the private key for the
// certificate which was used to encrypt the information. |client_id| must
@@ -86,6 +92,7 @@ class DrmServiceCertificate {
const std::string& certificate() const { return certificate_; }
const std::string& provider_id() const { return provider_id_; }
const std::string& serial_number() const { return serial_number_; }
uint32_t creation_time_seconds() const { return creation_time_seconds_; }
const RsaPrivateKey* const private_key() const { return private_key_.get(); }
const RsaPublicKey* const public_key() const { return public_key_.get(); }

View File

@@ -160,6 +160,9 @@ TEST_F(DrmServiceCertificateTest, MultipleDrmServiceCertificates) {
uint32_t creation_time_seconds1(1234);
std::string serial_number2("serial_number2");
uint32_t creation_time_seconds2(1234);
std::string serial_number3("serial_number3");
std::string provider_id3("service3.com");
uint32_t creation_time_seconds3(1235);
std::string bogus_serial_number("bogus-serial-number2");
EXPECT_EQ(nullptr, DrmServiceCertificate::GetDefaultDrmServiceCertificate());
@@ -172,6 +175,9 @@ TEST_F(DrmServiceCertificateTest, MultipleDrmServiceCertificates) {
EXPECT_OK(AddDrmServiceCertificate(serial_number2, provider_id1,
creation_time_seconds2));
EXPECT_OK(AddDrmServiceCertificate(serial_number3, provider_id3,
creation_time_seconds3));
EncryptedClientIdentification encrypted_client_id;
EncryptClientIdentification(serial_number1, provider_id1,
test_keys_.public_test_key_2_2048_bits(),
@@ -199,6 +205,61 @@ TEST_F(DrmServiceCertificateTest, MultipleDrmServiceCertificates) {
.error_code());
}
TEST_F(DrmServiceCertificateTest, MultipleDrmServiceCertificatesLookup) {
std::string serial_number1("serial_number1");
std::string provider_id1("service1.com");
uint32_t creation_time_seconds1(1231);
std::string serial_number2("serial_number2");
std::string provider_id2("service2.com");
uint32_t creation_time_seconds2(1232);
std::string serial_number3("serial_number3");
std::string provider_id3("service3.com");
uint32_t creation_time_seconds3(1234);
std::string serial_number4("serial_number4");
std::string bogus_serial_number("bogus-serial-number");
EXPECT_OK(AddDrmServiceCertificate(serial_number1, provider_id1,
creation_time_seconds1));
EXPECT_OK(AddDrmServiceCertificate(serial_number2, provider_id2,
creation_time_seconds2));
EXPECT_OK(AddDrmServiceCertificate(serial_number3, provider_id3,
creation_time_seconds3));
EXPECT_EQ(provider_id1,
DrmServiceCertificate::GetDrmServiceCertificateBySerialNumber(
serial_number1)
->provider_id());
EXPECT_EQ(provider_id2,
DrmServiceCertificate::GetDrmServiceCertificateBySerialNumber(
serial_number2)
->provider_id());
EXPECT_EQ(provider_id3,
DrmServiceCertificate::GetDrmServiceCertificateBySerialNumber(
serial_number3)
->provider_id());
EXPECT_EQ(
serial_number1,
DrmServiceCertificate::GetDrmServiceCertificateByProvider(provider_id1)
->serial_number());
EXPECT_EQ(
serial_number2,
DrmServiceCertificate::GetDrmServiceCertificateByProvider(provider_id2)
->serial_number());
EXPECT_EQ(
serial_number3,
DrmServiceCertificate::GetDrmServiceCertificateByProvider(provider_id3)
->serial_number());
// Add a second cert for provider 3.
EXPECT_OK(AddDrmServiceCertificate(serial_number4, provider_id3,
creation_time_seconds3 + 60));
EXPECT_EQ(
serial_number4,
DrmServiceCertificate::GetDrmServiceCertificateByProvider(provider_id3)
->serial_number());
}
TEST_F(DrmServiceCertificateTest, MultipleCertsPerService) {
std::string serial_number1("serial_number1");
std::string serial_number2("serial_number2");

View File

@@ -250,7 +250,130 @@ const unsigned char kTestUserDrmCertificate[] = {
0x82, 0xc8, 0xff, 0x4d, 0xef, 0x98, 0xcf, 0xb5, 0x6f, 0x6b, 0x55, 0xf8,
0xd4, 0x4a, 0xa2, 0x84, 0x3c, 0xec, 0x1a};
const unsigned char kTestDrmServiceCertificate[] = {
const unsigned char kTestDrmServiceCertificateLicenseSdk[] = {
0x0a, 0xbe, 0x02, 0x08, 0x03, 0x12, 0x10, 0x30, 0x30, 0x31, 0x31, 0x32,
0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x37, 0x18,
0xb1, 0x97, 0xd3, 0x03, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a, 0x02,
0x82, 0x01, 0x01, 0x00, 0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54,
0x5a, 0x2a, 0x40, 0xb4, 0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, 0x94, 0x58,
0xdd, 0xde, 0xa7, 0x1f, 0x3c, 0x2c, 0xe0, 0x88, 0x09, 0x29, 0x61, 0x57,
0x67, 0x5e, 0x56, 0x7e, 0xee, 0x27, 0x8f, 0x59, 0x34, 0x9a, 0x2a, 0xaa,
0x9d, 0xb4, 0x4e, 0xfa, 0xa7, 0x6a, 0xd4, 0xc9, 0x7a, 0x53, 0xc1, 0x4e,
0x9f, 0xe3, 0x34, 0xf7, 0x3d, 0xb7, 0xc9, 0x10, 0x47, 0x4f, 0x28, 0xda,
0x3f, 0xce, 0x31, 0x7b, 0xfd, 0x06, 0x10, 0xeb, 0xf7, 0xbe, 0x92, 0xf9,
0xaf, 0xfb, 0x3e, 0x68, 0xda, 0xee, 0x1a, 0x64, 0x4c, 0xf3, 0x29, 0xf2,
0x73, 0x9e, 0x39, 0xd8, 0xf6, 0x6f, 0xd8, 0xb2, 0x80, 0x82, 0x71, 0x8e,
0xb5, 0xa4, 0xf2, 0xc2, 0x3e, 0xcd, 0x0a, 0xca, 0xb6, 0x04, 0xcd, 0x9a,
0x13, 0x8b, 0x54, 0x73, 0x54, 0x25, 0x54, 0x8c, 0xbe, 0x98, 0x7a, 0x67,
0xad, 0xda, 0xb3, 0x4e, 0xb3, 0xfa, 0x82, 0xa8, 0x4a, 0x67, 0x98, 0x56,
0x57, 0x54, 0x71, 0xcd, 0x12, 0x7f, 0xed, 0xa3, 0x01, 0xc0, 0x6a, 0x8b,
0x24, 0x03, 0x96, 0x88, 0xbe, 0x97, 0x66, 0x2a, 0xbc, 0x53, 0xc9, 0x83,
0x06, 0x51, 0x5a, 0x88, 0x65, 0x13, 0x18, 0xe4, 0x3a, 0xed, 0x6b, 0xf1,
0x61, 0x5b, 0x4c, 0xc8, 0x1e, 0xf4, 0xc2, 0xae, 0x08, 0x5e, 0x2d, 0x5f,
0xf8, 0x12, 0x7f, 0xa2, 0xfc, 0xbb, 0x21, 0x18, 0x30, 0xda, 0xfe, 0x40,
0xfb, 0x01, 0xca, 0x2e, 0x37, 0x0e, 0xce, 0xdd, 0x76, 0x87, 0x82, 0x46,
0x0b, 0x3a, 0x77, 0x8f, 0xc0, 0x72, 0x07, 0x2c, 0x7f, 0x9d, 0x1e, 0x86,
0x5b, 0xed, 0x27, 0x29, 0xdf, 0x03, 0x97, 0x62, 0xef, 0x44, 0xd3, 0x5b,
0x3d, 0xdb, 0x9c, 0x5e, 0x1b, 0x7b, 0x39, 0xb4, 0x0b, 0x6d, 0x04, 0x6b,
0xbb, 0xbb, 0x2c, 0x5f, 0xcf, 0xb3, 0x7a, 0x05, 0x02, 0x03, 0x01, 0x00,
0x01, 0x3a, 0x10, 0x73, 0x6f, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x40, 0x01, 0x12, 0x80, 0x03,
0x1e, 0xa4, 0x3f, 0x68, 0x74, 0x1c, 0xcd, 0x8c, 0xa3, 0xfe, 0xa7, 0x08,
0x95, 0x31, 0x32, 0x97, 0x9b, 0x0a, 0x20, 0x55, 0x5a, 0xc3, 0xbb, 0x1c,
0xf8, 0x04, 0x9c, 0x31, 0x26, 0xc0, 0x93, 0xb3, 0x18, 0x5b, 0x98, 0x23,
0x8f, 0xc3, 0x7e, 0xdf, 0x59, 0xa5, 0x30, 0xb6, 0x2e, 0x13, 0x14, 0xd6,
0xfd, 0x24, 0xf1, 0xca, 0x6a, 0x9f, 0x5b, 0xe0, 0x0e, 0x73, 0x43, 0xd9,
0x7a, 0x2e, 0x05, 0x1c, 0x9e, 0x95, 0xc1, 0x0a, 0xa6, 0x1a, 0xcc, 0x96,
0x91, 0x03, 0x39, 0xaf, 0xd5, 0xb5, 0xdf, 0x0a, 0xa7, 0x51, 0x1d, 0x6c,
0x31, 0xa7, 0x24, 0x06, 0x5b, 0x14, 0x25, 0xff, 0x8f, 0x88, 0x83, 0x81,
0xc3, 0xb5, 0xf8, 0x3e, 0xa8, 0x0e, 0xe7, 0xe4, 0x5b, 0x83, 0xad, 0xc0,
0xe8, 0x31, 0x2d, 0x22, 0x11, 0x3e, 0xed, 0xd4, 0xde, 0x41, 0x49, 0x08,
0x37, 0x6d, 0x3e, 0x27, 0x2e, 0x89, 0xc0, 0x9f, 0x9c, 0x75, 0xfa, 0xff,
0x54, 0x22, 0x6f, 0x3f, 0x0d, 0x38, 0x4f, 0xb1, 0x49, 0xd3, 0xef, 0x37,
0x80, 0x39, 0x41, 0x1f, 0x03, 0x93, 0xd1, 0x19, 0xb1, 0xba, 0x61, 0xa7,
0x86, 0xbb, 0x3f, 0xd3, 0xa2, 0x1a, 0xa3, 0x8a, 0xfa, 0xef, 0x14, 0x36,
0xe1, 0xec, 0xfd, 0x7d, 0xcc, 0xe5, 0x8d, 0x3e, 0x4c, 0x30, 0xa7, 0x9e,
0x59, 0xe6, 0x27, 0xf2, 0xed, 0x07, 0xc8, 0x18, 0xf2, 0x14, 0x4c, 0x25,
0x0e, 0x72, 0xdd, 0x75, 0x9e, 0x8b, 0xf9, 0x41, 0xac, 0x5b, 0x26, 0x2d,
0x56, 0x0d, 0x18, 0x3d, 0xaa, 0x16, 0x48, 0x7c, 0xd1, 0x09, 0x89, 0x68,
0xac, 0x95, 0x06, 0xce, 0xa8, 0xfa, 0x93, 0x10, 0x60, 0xe3, 0x43, 0x26,
0x16, 0x0b, 0xbc, 0x44, 0x40, 0x02, 0xf5, 0x72, 0x87, 0x70, 0x08, 0x92,
0x28, 0xcb, 0xa8, 0x14, 0x41, 0xbf, 0x59, 0xaa, 0x14, 0x0c, 0x10, 0x2f,
0x1d, 0x89, 0xe4, 0x1e, 0x83, 0x76, 0x48, 0x82, 0x1f, 0x3c, 0x63, 0x36,
0x6b, 0xaa, 0x33, 0x4f, 0xe0, 0x00, 0x4b, 0x48, 0x71, 0x39, 0x5e, 0x85,
0xd4, 0x47, 0x7a, 0x31, 0x0a, 0x3b, 0x31, 0x90, 0x28, 0x1c, 0x4e, 0x4e,
0x3e, 0xb2, 0x02, 0xf0, 0xb9, 0x71, 0xe3, 0xef, 0x22, 0x63, 0xf2, 0x97,
0x9c, 0xe8, 0x16, 0xfc, 0x06, 0xa4, 0xf8, 0xfa, 0xe6, 0xd2, 0x82, 0x7f,
0xd5, 0x70, 0x9b, 0xd8, 0xb9, 0xcd, 0xbc, 0xc6, 0x9d, 0xd3, 0x52, 0xf7,
0x05, 0xa6, 0x25, 0xb8, 0x71, 0x3c, 0x15, 0x29, 0x36, 0xab, 0xb2, 0xa2,
0xc7, 0xe5, 0xa1, 0x0b, 0x85, 0x4d, 0xa5, 0xb5, 0x4f, 0xda, 0xcd, 0x0a,
0x8e, 0x8a, 0xbd, 0x2e, 0xf1, 0x2b, 0x0e, 0xdb, 0xf7, 0x9c, 0x9d, 0xcb,
0x69, 0xe0, 0x37, 0xea, 0xb1, 0x32, 0x71, 0x09, 0x4f, 0x72, 0x42, 0x3c,
0xdf, 0xe9, 0x5c, 0x40, 0x28, 0x32, 0x82, 0xb2, 0x4e, 0x77, 0xdd, 0x06};
const unsigned char kTestDrmServiceCertificateAllTypes[] = {
0x0a, 0xc2, 0x02, 0x08, 0x03, 0x12, 0x10, 0x30, 0x30, 0x31, 0x31, 0x32,
0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x37, 0x18,
0xb1, 0x97, 0xd3, 0x03, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a, 0x02,
0x82, 0x01, 0x01, 0x00, 0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54,
0x5a, 0x2a, 0x40, 0xb4, 0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, 0x94, 0x58,
0xdd, 0xde, 0xa7, 0x1f, 0x3c, 0x2c, 0xe0, 0x88, 0x09, 0x29, 0x61, 0x57,
0x67, 0x5e, 0x56, 0x7e, 0xee, 0x27, 0x8f, 0x59, 0x34, 0x9a, 0x2a, 0xaa,
0x9d, 0xb4, 0x4e, 0xfa, 0xa7, 0x6a, 0xd4, 0xc9, 0x7a, 0x53, 0xc1, 0x4e,
0x9f, 0xe3, 0x34, 0xf7, 0x3d, 0xb7, 0xc9, 0x10, 0x47, 0x4f, 0x28, 0xda,
0x3f, 0xce, 0x31, 0x7b, 0xfd, 0x06, 0x10, 0xeb, 0xf7, 0xbe, 0x92, 0xf9,
0xaf, 0xfb, 0x3e, 0x68, 0xda, 0xee, 0x1a, 0x64, 0x4c, 0xf3, 0x29, 0xf2,
0x73, 0x9e, 0x39, 0xd8, 0xf6, 0x6f, 0xd8, 0xb2, 0x80, 0x82, 0x71, 0x8e,
0xb5, 0xa4, 0xf2, 0xc2, 0x3e, 0xcd, 0x0a, 0xca, 0xb6, 0x04, 0xcd, 0x9a,
0x13, 0x8b, 0x54, 0x73, 0x54, 0x25, 0x54, 0x8c, 0xbe, 0x98, 0x7a, 0x67,
0xad, 0xda, 0xb3, 0x4e, 0xb3, 0xfa, 0x82, 0xa8, 0x4a, 0x67, 0x98, 0x56,
0x57, 0x54, 0x71, 0xcd, 0x12, 0x7f, 0xed, 0xa3, 0x01, 0xc0, 0x6a, 0x8b,
0x24, 0x03, 0x96, 0x88, 0xbe, 0x97, 0x66, 0x2a, 0xbc, 0x53, 0xc9, 0x83,
0x06, 0x51, 0x5a, 0x88, 0x65, 0x13, 0x18, 0xe4, 0x3a, 0xed, 0x6b, 0xf1,
0x61, 0x5b, 0x4c, 0xc8, 0x1e, 0xf4, 0xc2, 0xae, 0x08, 0x5e, 0x2d, 0x5f,
0xf8, 0x12, 0x7f, 0xa2, 0xfc, 0xbb, 0x21, 0x18, 0x30, 0xda, 0xfe, 0x40,
0xfb, 0x01, 0xca, 0x2e, 0x37, 0x0e, 0xce, 0xdd, 0x76, 0x87, 0x82, 0x46,
0x0b, 0x3a, 0x77, 0x8f, 0xc0, 0x72, 0x07, 0x2c, 0x7f, 0x9d, 0x1e, 0x86,
0x5b, 0xed, 0x27, 0x29, 0xdf, 0x03, 0x97, 0x62, 0xef, 0x44, 0xd3, 0x5b,
0x3d, 0xdb, 0x9c, 0x5e, 0x1b, 0x7b, 0x39, 0xb4, 0x0b, 0x6d, 0x04, 0x6b,
0xbb, 0xbb, 0x2c, 0x5f, 0xcf, 0xb3, 0x7a, 0x05, 0x02, 0x03, 0x01, 0x00,
0x01, 0x3a, 0x10, 0x73, 0x6f, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x40, 0x01, 0x40, 0x02, 0x40,
0x03, 0x12, 0x80, 0x03, 0x78, 0x86, 0x5a, 0xfa, 0x0f, 0x0d, 0x39, 0x6c,
0x19, 0x33, 0x24, 0x2d, 0x20, 0xbd, 0x34, 0xcc, 0x6e, 0xb8, 0x68, 0x36,
0x8d, 0x75, 0xc6, 0xbe, 0x6f, 0x8b, 0x98, 0x53, 0x4f, 0xed, 0x6e, 0x78,
0x2e, 0x15, 0xde, 0x82, 0x37, 0xa3, 0xc5, 0x1f, 0x82, 0xb4, 0xec, 0x4b,
0x5f, 0xb3, 0xd8, 0x99, 0xf4, 0xb1, 0x9a, 0x49, 0x15, 0xd8, 0x80, 0xcc,
0x7c, 0x16, 0xd9, 0xd8, 0x57, 0x59, 0x36, 0x34, 0xd0, 0x0e, 0xbb, 0x62,
0x76, 0x96, 0x73, 0x3b, 0xd9, 0xea, 0x61, 0x16, 0x3d, 0xdd, 0x38, 0xef,
0x25, 0x13, 0xbd, 0xe4, 0xa8, 0x69, 0x17, 0x81, 0x79, 0x2a, 0xe3, 0x29,
0xac, 0x68, 0xb1, 0x5f, 0x4e, 0x5f, 0xb5, 0x45, 0x71, 0xa6, 0x38, 0x6d,
0xce, 0x90, 0x7e, 0x0c, 0x5a, 0x7b, 0x6a, 0xce, 0xfa, 0x77, 0xf2, 0x57,
0xa9, 0x2f, 0x8e, 0xc1, 0x0f, 0x9b, 0x0f, 0xe1, 0xf5, 0x6e, 0x12, 0xf4,
0xac, 0x43, 0x95, 0x72, 0x73, 0x75, 0x0d, 0x3f, 0xc5, 0xac, 0x82, 0x04,
0x79, 0xab, 0x01, 0xc1, 0x71, 0x67, 0x3a, 0x0d, 0xf0, 0xa7, 0x74, 0x94,
0xd8, 0xe3, 0xf4, 0x3d, 0x92, 0x6b, 0x62, 0x63, 0xad, 0x3a, 0x95, 0x1a,
0x84, 0x00, 0x2d, 0x4b, 0x06, 0x8a, 0x26, 0x65, 0xa9, 0xeb, 0xb4, 0x4f,
0x7f, 0x66, 0x32, 0x59, 0x55, 0x89, 0x1d, 0x00, 0x5e, 0xed, 0x53, 0x4f,
0x36, 0xce, 0xc9, 0x9b, 0xfb, 0xa4, 0x04, 0x3a, 0x2f, 0xd9, 0x68, 0x9c,
0x98, 0xf3, 0xfc, 0xc6, 0x07, 0xc2, 0x00, 0x17, 0x39, 0x27, 0xb4, 0x13,
0x49, 0x23, 0x4a, 0xf4, 0x96, 0xf1, 0x3e, 0x5d, 0x66, 0x04, 0xe2, 0x93,
0xf9, 0x2c, 0x08, 0xa7, 0x08, 0x65, 0x39, 0x0f, 0xa9, 0xec, 0x55, 0x24,
0xab, 0x46, 0x32, 0x48, 0xd0, 0xd2, 0x44, 0x64, 0x29, 0x0d, 0xd5, 0x26,
0x4d, 0x85, 0xbb, 0x79, 0x7d, 0xa0, 0xf3, 0x83, 0x02, 0xe0, 0x4f, 0xd7,
0xa0, 0x55, 0x9f, 0x20, 0x4e, 0x58, 0x0b, 0x39, 0xbc, 0x2b, 0xa0, 0x1f,
0x98, 0x46, 0x3d, 0x96, 0xc0, 0xff, 0x43, 0x78, 0xdc, 0x49, 0x89, 0xf4,
0x01, 0x83, 0xec, 0x33, 0x4c, 0x8a, 0xe0, 0x6c, 0x92, 0x95, 0xfd, 0x74,
0x2e, 0x55, 0x86, 0xc8, 0x54, 0x7c, 0x63, 0xce, 0x58, 0xe6, 0xfc, 0xc1,
0xc3, 0x9d, 0x67, 0x85, 0xe8, 0xa1, 0x4d, 0x11, 0xb2, 0xbe, 0x9f, 0x70,
0x32, 0x08, 0x67, 0x3a, 0x07, 0xd5, 0xf5, 0xdf, 0xc1, 0x40, 0x8a, 0x60,
0xc1, 0x1e, 0xa7, 0x64, 0x23, 0x1d, 0x93, 0x3b, 0xfa, 0x64, 0x87, 0x64,
0xfc, 0x09, 0x1c, 0xad, 0xf8, 0x44, 0x5b, 0x1d, 0x75, 0xde, 0x7c, 0xf2,
0x9e, 0x9f, 0x17, 0xa0, 0xb4, 0x33, 0xc7, 0x5c, 0x73, 0x19, 0x61, 0x7b,
0xde, 0xff, 0x0c, 0xf9, 0x66, 0x99, 0xf1, 0xae, 0x42, 0x04, 0x65, 0xf2,
0x56, 0xdc, 0x1a, 0x8d};
const unsigned char kTestDrmServiceCertificateNoType[] = {
0x0a, 0xbc, 0x02, 0x08, 0x03, 0x12, 0x10, 0x30, 0x30, 0x31, 0x31, 0x32,
0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x37, 0x18,
0xb1, 0x97, 0xd3, 0x03, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a, 0x02,
@@ -321,8 +444,17 @@ TestDrmCertificates::TestDrmCertificates()
test_user_device_certificate_(
kTestUserDrmCertificate,
kTestUserDrmCertificate + sizeof(kTestUserDrmCertificate)),
test_service_certificate_(
kTestDrmServiceCertificate,
kTestDrmServiceCertificate + sizeof(kTestDrmServiceCertificate)) {}
test_service_certificate_license_sdk_(
kTestDrmServiceCertificateLicenseSdk,
kTestDrmServiceCertificateLicenseSdk +
sizeof(kTestDrmServiceCertificateLicenseSdk)),
test_service_certificate_all_types_(
kTestDrmServiceCertificateAllTypes,
kTestDrmServiceCertificateAllTypes +
sizeof(kTestDrmServiceCertificateAllTypes)),
test_service_certificate_no_type_(
kTestDrmServiceCertificateNoType,
kTestDrmServiceCertificateNoType +
sizeof(kTestDrmServiceCertificateNoType)) {}
} // namespace widevine

View File

@@ -36,16 +36,29 @@ class TestDrmCertificates {
return test_user_device_certificate_;
}
// returns a service certificate
const std::string& test_service_certificate() const {
return test_service_certificate_;
// returns a service certificate with license sdk service type
const std::string& test_service_certificate_license_sdk() const {
return test_service_certificate_license_sdk_;
}
// returns a service certificate with all service types
const std::string& test_service_certificate_all_types() const {
return test_service_certificate_all_types_;
}
// returns a service certificate prior to a change requiring the service
// type to be specified.
const std::string& test_service_certificate_no_type() const {
return test_service_certificate_no_type_;
}
private:
const std::string test_root_certificate_;
const std::string test_intermediate_certificate_;
const std::string test_user_device_certificate_;
const std::string test_service_certificate_;
const std::string test_service_certificate_license_sdk_;
const std::string test_service_certificate_all_types_;
const std::string test_service_certificate_no_type_;
DISALLOW_COPY_AND_ASSIGN(TestDrmCertificates);
};