Tools release: 1.1.1
This commit is contained in:
BIN
tools/bin/published_devices_client/published_devices_cli_deploy.jar
Executable file
BIN
tools/bin/published_devices_client/published_devices_cli_deploy.jar
Executable file
Binary file not shown.
BIN
tools/bin/published_devices_delta/published_devices_delta_deploy.jar
Executable file
BIN
tools/bin/published_devices_delta/published_devices_delta_deploy.jar
Executable file
Binary file not shown.
369
tools/source/published_devices_client/WORKSPACE
Normal file
369
tools/source/published_devices_client/WORKSPACE
Normal file
@@ -0,0 +1,369 @@
|
||||
# JTS Framework WORKSPACE.
|
||||
|
||||
workspace(name = "jts")
|
||||
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository", "git_repository")
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
# In Bazel 2.0, Maven rules provided via new rules_jvm_external.
|
||||
RULES_JVM_EXTERNAL_TAG = "3.1"
|
||||
RULES_JVM_EXTERNAL_SHA = "e246373de2353f3d34d35814947aa8b7d0dd1a58c2f7a6c41cfeaff3007c2d14"
|
||||
http_archive(
|
||||
name = "rules_jvm_external",
|
||||
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
|
||||
sha256 = RULES_JVM_EXTERNAL_SHA,
|
||||
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
|
||||
)
|
||||
load("@rules_jvm_external//:defs.bzl", "maven_install")
|
||||
|
||||
# Google Guice.
|
||||
maven_install(
|
||||
name = "google_guice",
|
||||
artifacts = ["com.google.inject:guice:4.2.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Appache core framework.
|
||||
maven_install(
|
||||
name = "apache_httpcore",
|
||||
artifacts = ["org.apache.httpcomponents:httpcore:4.4.10"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google APIs client library
|
||||
maven_install(
|
||||
name = "google_api",
|
||||
artifacts = ["com.google.api-client:google-api-client:1.30.2"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google HTTP Client
|
||||
maven_install(
|
||||
name = "google_http_client",
|
||||
artifacts = ["com.google.http-client:google-http-client:1.30.2"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google HTTP Client Jackson2 Extensions
|
||||
maven_install(
|
||||
name = "jackson2",
|
||||
artifacts = ["com.google.http-client:google-http-client-jackson2:1.31.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "jackson_core",
|
||||
artifacts = ["com.fasterxml.jackson.core:jackson-core:2.10.0.pr2"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google Oauth2 API
|
||||
maven_install(
|
||||
name = "google_oauth2",
|
||||
artifacts = ["com.google.oauth-client:google-oauth-client:1.30.1"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google Java common framework.
|
||||
maven_install(
|
||||
name = "google_guava",
|
||||
artifacts = ["com.google.guava:guava:25.1-jre"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GRPC
|
||||
git_repository(
|
||||
name = "io_grpc_grpc_java",
|
||||
remote = "https://github.com/grpc/grpc-java.git",
|
||||
tag = "v1.23.0",
|
||||
)
|
||||
|
||||
# GRPC Core
|
||||
maven_install(
|
||||
name = "grpc_core",
|
||||
artifacts = ["io.grpc:grpc-core:1.23.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GRPC Netty
|
||||
maven_install(
|
||||
name = "grpc_netty",
|
||||
artifacts = ["io.grpc:grpc-netty:1.23.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "grpc_netty_all",
|
||||
artifacts = ["io.netty:netty-all:4.1.41.Final"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GRPC Stub
|
||||
maven_install(
|
||||
name = "grpc_stub",
|
||||
artifacts = ["io.grpc:grpc-stub:1.23.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GRPC Contenxt
|
||||
maven_install(
|
||||
name = "grpc_context",
|
||||
artifacts = ["io.grpc:grpc-context:1.18.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GSON
|
||||
maven_install(
|
||||
name = "gson",
|
||||
artifacts = ["com.google.code.gson:gson:2.8.6"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Netty TcNative (for GRPC)
|
||||
maven_install(
|
||||
name = "netty_tcnative",
|
||||
artifacts = ["io.netty:netty-tcnative:2.0.25.Final"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Netty BoringSSL
|
||||
maven_install(
|
||||
name = "netty_boringssl",
|
||||
artifacts = ["io.netty:netty-tcnative-boringssl-static:2.0.25.Final"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Open Census (for GRPC)
|
||||
maven_install(
|
||||
name = "open_census_api",
|
||||
artifacts = ["io.opencensus:opencensus-api:0.24.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "open_census",
|
||||
artifacts = ["io.opencensus:opencensus-contrib-http-jetty-client:0.19.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "open_census_util",
|
||||
artifacts = ["io.opencensus:opencensus-contrib-http-util:0.19.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "open_census_grpc_metrics",
|
||||
artifacts = ["io.opencensus:opencensus-contrib-grpc-metrics:0.24.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Perfmark (GRPC)
|
||||
maven_install(
|
||||
name = "io_perfmark_api",
|
||||
artifacts = ["io.perfmark:perfmark-api:0.17.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google Protobuf Protos
|
||||
PROTOBUF_BUILD_FILE = """
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
PROTO_FILES = [
|
||||
"google/protobuf/descriptor.proto",
|
||||
]
|
||||
|
||||
filegroup(
|
||||
name = "protobuf_files",
|
||||
srcs = PROTO_FILES,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "protobuf_protos",
|
||||
srcs = [":protobuf_files"],
|
||||
visibility = ["//visibility:public"],
|
||||
|
||||
)
|
||||
"""
|
||||
|
||||
git_repository(
|
||||
name = "com_github_googleapis_googleapis",
|
||||
remote = "https://github.com/googleapis/googleapis.git",
|
||||
branch = "master",
|
||||
)
|
||||
load("@com_github_googleapis_googleapis//:repository_rules.bzl", "switched_rules_by_language")
|
||||
switched_rules_by_language(
|
||||
name = "com_google_googleapis_imports",
|
||||
java = True)
|
||||
|
||||
http_archive(
|
||||
name = "common_protos",
|
||||
build_file_content = PROTOBUF_BUILD_FILE,
|
||||
strip_prefix = "protobuf-3.9.1/src",
|
||||
urls = [
|
||||
"https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protobuf-all-3.9.1.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
# Java commandline framework.
|
||||
maven_install(
|
||||
name = "jcommander",
|
||||
artifacts = ["com.beust:jcommander:1.72"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
#Javax Inject (for Guice).
|
||||
maven_install(
|
||||
name = "javax_inject",
|
||||
artifacts = ["javax.inject:javax.inject:1"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# JSON Java.
|
||||
maven_install(
|
||||
name = "json",
|
||||
artifacts = ["org.json:json:20090211"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# JSR305 Annotations.
|
||||
maven_install(
|
||||
name = "jsr305_annotations",
|
||||
artifacts = ["com.google.code.findbugs:jsr305:3.0.2"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# AOP (for Guice).
|
||||
maven_install(
|
||||
name = "aopalliance",
|
||||
artifacts = ["aopalliance:aopalliance:1.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Protocol Buffer compiler.
|
||||
git_repository(
|
||||
name = "com_google_protobuf",
|
||||
remote = "https://github.com/google/protobuf.git",
|
||||
tag = "v3.9.1",
|
||||
)
|
||||
|
||||
bind(
|
||||
name = "protobuf",
|
||||
actual = "@com_google_protobuf//:protobuf",
|
||||
)
|
||||
|
||||
bind(
|
||||
name = "protobuf_java",
|
||||
actual = "@com_google_protobuf//:protobuf_java",
|
||||
)
|
||||
|
||||
# Loads necessary bazel rules for later consumption.
|
||||
load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories")
|
||||
grpc_java_repositories()
|
||||
|
||||
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||
protobuf_deps()
|
||||
@@ -0,0 +1,40 @@
|
||||
# Copyright 2019 Google LLC. All rights reserved.
|
||||
|
||||
# Published Devices protocol buffer definitions for the
|
||||
# Widevine Published Devices One Platform API service.
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
|
||||
|
||||
proto_library(
|
||||
name = "published_devices_proto",
|
||||
srcs = ["published_devices.proto"],
|
||||
deps = [
|
||||
":device_security_profiles_proto",
|
||||
"@com_github_googleapis_googleapis//google/api:annotations_proto",
|
||||
"@com_github_googleapis_googleapis//google/api:field_behavior_proto",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "device_security_profiles_proto",
|
||||
srcs = ["device_security_profiles.proto"],
|
||||
deps = [
|
||||
"@com_github_googleapis_googleapis//google/api:field_behavior_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "published_devices_java_proto",
|
||||
deps = [":published_devices_proto"],
|
||||
|
||||
)
|
||||
|
||||
java_grpc_library(
|
||||
name = "published_devices_grpc",
|
||||
srcs = [":published_devices_proto"],
|
||||
deps = [
|
||||
":published_devices_java_proto",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,94 @@
|
||||
// This file contains the proto definitions of DeviceSecurityProfile needed for
|
||||
// the PublishedDevicesService.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.chrome.widevine.contentpartners.v1beta1;
|
||||
|
||||
import "google/api/field_behavior.proto";
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "DeviceSecurityProfilesProto";
|
||||
option java_package = "com.google.chrome.widevine.contentpartners.v1beta1";
|
||||
|
||||
// The DeviceSecurityProfileCriteria is produced by the client (a Widevine
|
||||
// SDK). It is serialized and embedded in the
|
||||
// ListDeviceSecurityProfilesRequest.
|
||||
message DeviceSecurityProfileCriteria {
|
||||
// Content provider who wants to get the DSPs. Required.
|
||||
string content_provider = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
// Content owners who own the DSPs. If this field is empty, return all
|
||||
// DSPs that the content provider is included. Otherwise, a list of DSPs
|
||||
// owned by the listed content_owners would be filtered for the requested
|
||||
// provider. Optional field.
|
||||
repeated string content_owners = 2 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
// A request sent to Widevine Published Server to retrieve
|
||||
// the DeviceSecurityProfiles.
|
||||
// (-- api-linter: core::0132::request-unknown-fields=disabled
|
||||
// api-linter: core::0132::request-parent-required=disabled
|
||||
// api-linter: core::0158::request-page-token-field=disabled
|
||||
// api-linter: core::0158::request-page-size-field=disabled
|
||||
// aip.dev/not-precedent: This is a non-standard, non-precedent API that
|
||||
// cannot use pagination. It has no parent, page_size and page_token.
|
||||
// Pagination is not appropriate. --)
|
||||
message ListDeviceSecurityProfilesRequest {
|
||||
// DeviceSecurityProfileCriteria for List request. Required.
|
||||
DeviceSecurityProfileCriteria device_security_profile_criteria = 1
|
||||
[(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
||||
// A signed message which contains a serialized DeviceSecurityProfileList and
|
||||
// the signature.
|
||||
// (--GOOGLE_INTERNAL
|
||||
// This message is copied from
|
||||
// video/widevine/protos/public/device_security_profile_list.proto
|
||||
// --)
|
||||
message SignedDeviceSecurityProfiles {
|
||||
// Serialized DeviceSecurityProfileList. Required.
|
||||
// A device security profile list contains device security profiles
|
||||
// defined by the content owner. Each DSP aggregates the device's
|
||||
// capabilities, such as security profile level, minimum output requirements,
|
||||
// minimum security requirements for this profile. The information is intended
|
||||
// to be shared publicly.
|
||||
bytes device_security_profiles = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
// Signature of device_security_profiles. Signed with root
|
||||
// certificate private key using RSASSA-PSS. Required.
|
||||
bytes signature = 2 [(google.api.field_behavior) = REQUIRED];
|
||||
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
// A response returned from Widevine Published Server which contains a signed
|
||||
// DeviceSecurityProfileList message.
|
||||
// (-- api-linter: core::0132::response-unknown-fields=disabled
|
||||
// api-linter: core::0158::response-repeated-first-field=disabled
|
||||
// api-linter: core::0158::response-next-page-token-field=disabled
|
||||
// aip.dev/not-precedent: This is a non-standard, non-precedent API that
|
||||
// cannot use pagination. We serialize and sign the list data in a signed
|
||||
// message, which is used in the response. The first field is not repeated
|
||||
// and response has no next_page_token field. The
|
||||
// SignedDeviceSecurityProfiles is intended to be consumed as a single blob.
|
||||
// Pagination is not appropriate. --)
|
||||
message ListDeviceSecurityProfilesResponse {
|
||||
// A signed message which contains a serialized DeviceSecurityProfileList and
|
||||
// the signature.
|
||||
SignedDeviceSecurityProfiles signed_device_security_profiles = 1
|
||||
[(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
||||
// A representation of a hash algorithm used in signature.
|
||||
// (--GOOGLE_INTERNAL
|
||||
// This enum is copied from
|
||||
// video/widevine/protos/public/hash_algorithm.proto
|
||||
// --)
|
||||
enum HashAlgorithm {
|
||||
// Unspecified hash algorithm: SHA_256 shall be used for ECC based algorithms
|
||||
// and SHA_1 shall be used otherwise.
|
||||
HASH_ALGORITHM_UNSPECIFIED = 0;
|
||||
// Secure Hash Algorithm 1 (SHA-1).
|
||||
HASH_ALGORITHM_SHA_1 = 1;
|
||||
// Secure Hash Algorithm 2 256 bits (SHA-256).
|
||||
HASH_ALGORITHM_SHA_256 = 2;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// This file contains the definitions needed for the PublishedDevicesService.
|
||||
// The PublishedDevicesService allows clients to retrieve a signed and
|
||||
// verifiable list of devices and device security profiles that support the
|
||||
// Widevine Digital Rights Management (DRM) solution.
|
||||
//
|
||||
// (--GOOGLE_INTERNAL
|
||||
// This proto is intended to support a feature of the "Widevine API" where
|
||||
// external content providers will retrieve device certificate status list
|
||||
// as well as device secruity profiles to achieve better and more secure
|
||||
// playback experience.
|
||||
//
|
||||
// For more info about the service, please see design doc
|
||||
// https://docs.google.com/document/d/1ZClc0HJuFlijDrdZxcR_DmNOi6Hqo7bjjEtewLnafas/edit?usp=sharing
|
||||
// --)
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.chrome.widevine.contentpartners.v1beta1;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/chrome/widevine/contentpartners/v1beta1/device_security_profiles.proto";
|
||||
|
||||
option csharp_namespace = "Google.Chrome.Widevine.ContentPartners.V1Beta1";
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "PublishedDevicesProtos";
|
||||
option java_package = "com.google.chrome.widevine.contentpartners.v1beta1";
|
||||
|
||||
// GCWPD is an acronym for Google Chrome Widevine Published Devices.
|
||||
option objc_class_prefix = "GCWPD";
|
||||
|
||||
|
||||
// This service produces a list of Widevine supported devices
|
||||
// signed by a certificate that can be verified by the client.
|
||||
service PublishedDevicesService {
|
||||
// Return the PublishedDevices containing the list of devices and a signature.
|
||||
// The request is used to authenticate the client.
|
||||
rpc GetPublishedDevices(PublishedDevicesRequest) returns (PublishedDevices) {
|
||||
|
||||
option (google.api.http) = {
|
||||
post: "/v1beta1/publishedDevices:getSignedBatch"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// Return the ListDeviceSecurityProfilesResponse containing a list of
|
||||
// device security profiles.
|
||||
rpc ListDeviceSecurityProfiles(ListDeviceSecurityProfilesRequest)
|
||||
returns (ListDeviceSecurityProfilesResponse) {
|
||||
|
||||
option (google.api.http) = {
|
||||
get: "/v1beta1/deviceSecurityProfiles:listDeviceSecurityProfiles"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// The SdkClientInformation is produced by the client (a Widevine SDK). It is
|
||||
// serialized and embedded in the PublishedDevicesRequest. It is used to
|
||||
// declare attributes of the client's SDK including the Widevine-issued service
|
||||
// certificate that is used by the client.
|
||||
message SdkClientInformation {
|
||||
// The version of sdk. Required.
|
||||
string sdk_version = 1;
|
||||
// POSIX time, in seconds, when this request was created. Required.
|
||||
uint64 sdk_time_seconds = 2;
|
||||
// The serialized service certificate used to sign the request. Required.
|
||||
bytes service_certificate = 3;
|
||||
}
|
||||
|
||||
// A signed request sent to Widevine Provisioning Server (keysmith) to retrieve
|
||||
// the PublishedDevices.
|
||||
message PublishedDevicesRequest {
|
||||
// A serialized SdkClientInformation proto. Required.
|
||||
bytes sdk_client_information = 1;
|
||||
|
||||
// This is the SHA256 digest, PKCS#7 padded signature of the
|
||||
// sdk_client_information field. This signature uses the
|
||||
// RSA private key corresponding to the server certificate. Required.
|
||||
bytes signature = 2;
|
||||
|
||||
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
// Contains a serialized DeviceCertificateStatusList and the signature.
|
||||
message PublishedDevices {
|
||||
// Serialized DeviceCertificateStatusList. Required.
|
||||
// A device certificate status list contains information about various
|
||||
// device series information such as the make, model and status (RELEASED,
|
||||
// IN_TESTING, REVOKED, etc).The information is intended to be shared
|
||||
// publicly.
|
||||
bytes published_devices = 1;
|
||||
|
||||
// Signature of device_certificate_status_list_request. Signed with root
|
||||
// certificate private key using RSASSA-PSS. Required.
|
||||
bytes signature = 2;
|
||||
|
||||
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
21
tools/source/published_devices_client/httpclient/BUILD
Normal file
21
tools/source/published_devices_client/httpclient/BUILD
Normal file
@@ -0,0 +1,21 @@
|
||||
# Copyright 2019 Google LLC. All rights reserved.
|
||||
# Desciption:
|
||||
# JTS http clients.
|
||||
|
||||
package(
|
||||
default_visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "httpclient",
|
||||
srcs = glob(["*.java"]),
|
||||
deps = [
|
||||
"@google_guice//:com_google_inject_guice",
|
||||
"@json//:org_json_json",
|
||||
"@google_api//:com_google_api_client_google_api_client",
|
||||
"@google_http_client//:com_google_http_client_google_http_client",
|
||||
"@google_oauth2//:com_google_oauth_client_google_oauth_client",
|
||||
"@jackson2//:com_google_http_client_google_http_client_jackson2",
|
||||
"@jackson_core//:com_fasterxml_jackson_core_jackson_core",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved.
|
||||
package com.google.video.widevine.jts.httpclient;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* JTS Cloud Credentials.
|
||||
*
|
||||
* Provides Oauth2 authentication, and access/refresh tokens.
|
||||
*/
|
||||
public class Credentials {
|
||||
|
||||
private static final List<String> SCOPES = Arrays.asList(
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
"https://www.googleapis.com/auth/widevine/frontend");
|
||||
private static final int MIN_ACCESS_TOKEN_REFRESH_SEC = 1200;
|
||||
private static final Logger logger = Logger.getLogger(Credentials.class.getName());
|
||||
|
||||
private String credentialsJsonFile = null;
|
||||
private GoogleCredential googleCredential = null;
|
||||
private String accessToken = null;
|
||||
|
||||
/**
|
||||
* Credentials Constructor.
|
||||
*
|
||||
* @param credentialsJsonFile The full path to a GCP service account json credentials file.
|
||||
*/
|
||||
public Credentials(String credentialsJsonFile) throws IOException {
|
||||
this.credentialsJsonFile = credentialsJsonFile;
|
||||
activateGoogleCredentials();
|
||||
}
|
||||
|
||||
private void activateGoogleCredentials() throws IOException {
|
||||
googleCredential = GoogleCredential
|
||||
.fromStream(new FileInputStream(credentialsJsonFile))
|
||||
.createScoped(SCOPES);
|
||||
googleCredential.refreshToken();
|
||||
}
|
||||
|
||||
/** Provides an Oauth2 Access Token that can be used to make GCP service calls.*/
|
||||
public String getAccessToken() throws IOException {
|
||||
if (accessToken == null
|
||||
|| googleCredential.getExpiresInSeconds() <= MIN_ACCESS_TOKEN_REFRESH_SEC) {
|
||||
googleCredential.refreshToken();
|
||||
accessToken = googleCredential.getAccessToken();
|
||||
logger.log(Level.INFO, "Getting new access token.");
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
}
|
||||
17
tools/source/published_devices_client/interfaces/BUILD
Normal file
17
tools/source/published_devices_client/interfaces/BUILD
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright 2018 Google LLC. All rights reserved.
|
||||
# Desciption:
|
||||
# JTS interfaces.
|
||||
|
||||
package(
|
||||
default_visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "interfaces",
|
||||
srcs = glob(["*.java"]),
|
||||
deps = [
|
||||
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_java_proto",
|
||||
"@com_google_protobuf//:protobuf_java",
|
||||
"@apache_httpcore//:org_apache_httpcomponents_httpcore",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved.
|
||||
package com.google.video.widevine.jts.interfaces;
|
||||
|
||||
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevices;
|
||||
|
||||
/**
|
||||
* DeviceCertificate defines APIs for getting PublishedDevices and Published Devices list.
|
||||
*/
|
||||
public interface DeviceCertificate {
|
||||
|
||||
/**
|
||||
* Get the latest {@code PublishedDevices} containing Published Devices list data.
|
||||
*
|
||||
* @return {@code PublishedDevices} containing Published Devices list data.
|
||||
*/
|
||||
public PublishedDevices getPublishedDevices() throws Exception;
|
||||
|
||||
}
|
||||
37
tools/source/published_devices_client/providers/BUILD
Normal file
37
tools/source/published_devices_client/providers/BUILD
Normal file
@@ -0,0 +1,37 @@
|
||||
# Copyright 2018 Google LLC. All rights reserved.
|
||||
# Desciption:
|
||||
# JTS interfaces.
|
||||
|
||||
package(
|
||||
default_visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "providers",
|
||||
srcs = glob(["*.java"]),
|
||||
runtime_deps = [
|
||||
"@grpc_context//:io_grpc_grpc_context",
|
||||
"@grpc_netty_all//:io_netty_netty_all",
|
||||
"@io_perfmark_api//:io_perfmark_perfmark_api",
|
||||
"@netty_boringssl//:io_netty_netty_tcnative_boringssl_static",
|
||||
"@open_census//:io_opencensus_opencensus_contrib_http_jetty_client",
|
||||
"@open_census_api//:io_opencensus_opencensus_api",
|
||||
"@open_census_grpc_metrics//:io_opencensus_opencensus_contrib_grpc_metrics",
|
||||
"@open_census_util//:io_opencensus_opencensus_contrib_http_util",
|
||||
],
|
||||
deps = [
|
||||
":libwvpl_cas_proxy_sdk_lib.jar",
|
||||
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_grpc",
|
||||
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_java_proto",
|
||||
"//httpclient",
|
||||
"//interfaces",
|
||||
"@google_guice//:com_google_inject_guice",
|
||||
"@json//:org_json_json",
|
||||
"@com_google_protobuf//:protobuf_java",
|
||||
"@google_guava//:com_google_guava_guava",
|
||||
"@grpc_core//:io_grpc_grpc_core",
|
||||
"@grpc_netty//:io_grpc_grpc_netty",
|
||||
"@grpc_stub//:io_grpc_grpc_stub",
|
||||
"@io_grpc_grpc_java//api",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved.
|
||||
|
||||
package com.google.video.widevine.jts.providers;
|
||||
|
||||
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevices;
|
||||
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevicesRequest;
|
||||
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevicesServiceGrpc;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.protobuf.TextFormat;
|
||||
import com.google.video.widevine.jts.httpclient.Credentials;
|
||||
import com.google.video.widevine.jts.interfaces.DeviceCertificate;
|
||||
import com.google.video.widevine.sdk.wvpl.WvPLBaseEnvironment;
|
||||
import com.google.video.widevine.sdk.wvpl.WvPLStatusException;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.netty.NettyChannelBuilder;
|
||||
import io.grpc.stub.MetadataUtils;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Provides the latest {@code PublishedDevices} data from the Widevine Published Devices Service.
|
||||
*
|
||||
* This implementation uses the Widevine Published Devices API, and support a gRPC method for
|
||||
* retrieving PublishedDevices with an embedded Published Devices list.
|
||||
*/
|
||||
public class PublishedDevicesProvider implements DeviceCertificate {
|
||||
private static final Logger logger = Logger.getLogger(PublishedDevicesProvider.class.getName());
|
||||
private WvPLBaseEnvironment<?> environment = null;
|
||||
private String apiServicePath = null;
|
||||
private Credentials credentials = null;
|
||||
|
||||
/**
|
||||
* PublishedDevicesProvider constructor.
|
||||
*
|
||||
* @param environment A WvPLBaseEnvironment object initialized with a Service Certificate.
|
||||
* @param serviceAccountPath Path to a GCP Service Account json file, used in OAUTH.
|
||||
* @param apiServicePath Path to a Widevine Published Devices API service.
|
||||
* @throws IOException upon failure creating OAUTH credentials.
|
||||
*/
|
||||
@Inject
|
||||
public PublishedDevicesProvider(
|
||||
WvPLBaseEnvironment<?> environment, String serviceAccountPath, String apiServicePath)
|
||||
throws IOException {
|
||||
this.environment = environment;
|
||||
this.apiServicePath = apiServicePath;
|
||||
credentials = new Credentials(serviceAccountPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest {@code PublishedDevices} from the Widevine Published Devices Service.
|
||||
*
|
||||
* @return The latest {@code PublishedDevices} data.
|
||||
* @throws InterruptedException upon RPC failure.
|
||||
* @throws WvPLStatusException upon WvPLBaseEnvironment errors.
|
||||
*/
|
||||
@Override
|
||||
public PublishedDevices getPublishedDevices() throws InterruptedException, WvPLStatusException{
|
||||
ManagedChannel channel = null;
|
||||
PublishedDevices devicesResponse = null;
|
||||
|
||||
logger.log(Level.INFO, "Getting PublishedDevices...");
|
||||
try {
|
||||
channel = createRpcChannel(apiServicePath);
|
||||
Metadata metadata = new Metadata();
|
||||
String token = "Bearer " + credentials.getAccessToken();
|
||||
metadata.put(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER), token);
|
||||
PublishedDevicesServiceGrpc.PublishedDevicesServiceBlockingStub blockingStub =
|
||||
PublishedDevicesServiceGrpc.newBlockingStub(channel)
|
||||
.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata));
|
||||
devicesResponse = blockingStub.getPublishedDevices(PublishedDevicesRequest.parseFrom(
|
||||
environment.generateDeviceStatusListRequest()));
|
||||
logger.log(Level.INFO, "GRPC Call to PublishedDevicesService.GetSignedList returned:\n %s"
|
||||
+ TextFormat.printer().printToString(devicesResponse));
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.INFO, "IOException encountered trying to retrieve the signed list: " + e);
|
||||
} finally {
|
||||
if (channel != null) {
|
||||
channel.shutdown();
|
||||
channel.awaitTermination(1, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
return devicesResponse;
|
||||
}
|
||||
|
||||
private static ManagedChannel createRpcChannel(String host) {
|
||||
return NettyChannelBuilder.forTarget(host).build();
|
||||
}
|
||||
}
|
||||
39
tools/source/published_devices_client/tools/BUILD
Normal file
39
tools/source/published_devices_client/tools/BUILD
Normal file
@@ -0,0 +1,39 @@
|
||||
# Copyright 2019 Google LLC. All rights reserved.
|
||||
# Desciption:
|
||||
# JTS tools.
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
java_library(
|
||||
name = "published_devices_cli_lib",
|
||||
srcs = [
|
||||
"PublishedDevicesCli.java",
|
||||
],
|
||||
runtime_deps = [
|
||||
"@grpc_context//:io_grpc_grpc_context",
|
||||
"@grpc_netty_all//:io_netty_netty_all",
|
||||
"@io_perfmark_api//:io_perfmark_perfmark_api",
|
||||
"@netty_boringssl//:io_netty_netty_tcnative_boringssl_static",
|
||||
"@netty_tcnative//:io_netty_netty_tcnative",
|
||||
"@open_census//:io_opencensus_opencensus_contrib_http_jetty_client",
|
||||
"@open_census_api//:io_opencensus_opencensus_api",
|
||||
"@open_census_grpc_metrics//:io_opencensus_opencensus_contrib_grpc_metrics",
|
||||
"@open_census_util//:io_opencensus_opencensus_contrib_http_util",
|
||||
],
|
||||
deps = [
|
||||
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_grpc",
|
||||
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_java_proto",
|
||||
"//providers",
|
||||
"//providers:libwvpl_cas_proxy_sdk_lib.jar",
|
||||
"@jcommander//:com_beust_jcommander",
|
||||
"@google_guava//:com_google_guava_guava",
|
||||
],
|
||||
)
|
||||
|
||||
java_binary(
|
||||
name = "published_devices_cli",
|
||||
main_class = "com.google.video.widevine.jts.tools.PublishedDevicesCli",
|
||||
runtime_deps = [
|
||||
":published_devices_cli_lib",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,140 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved.
|
||||
|
||||
package com.google.video.widevine.jts.tools;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevices;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import com.google.video.widevine.jts.providers.PublishedDevicesProvider;
|
||||
import com.google.video.widevine.sdk.wvpl.WvPLCASProxyEnvironment;
|
||||
import com.google.video.widevine.sdk.wvpl.WvPLStatus;
|
||||
import com.google.video.widevine.sdk.wvpl.WvPLStatusException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Published Devices Command Line Interface.
|
||||
*
|
||||
* Provides a command line interface to get the latest {@code PublishedDevices} data from the
|
||||
* Widevine Published Devices Service.
|
||||
*
|
||||
* Default Widevine Service API path: widevine.googleapis.com.
|
||||
*
|
||||
* To build:
|
||||
* Bazel build java/com/google/video/widevine/jts/tools:published_devices_client_deploy.jar
|
||||
*
|
||||
* To run:
|
||||
* java -Djava.library.path=./path/to/license/sdk.so \
|
||||
* -jar /path/to/published_devices_client_deploy.jar \
|
||||
* -service_cert_path /path/to/cert_file.der \
|
||||
* -service_private_key_path /path/to/private_key.der \
|
||||
* -service_private_key_passphrase theprivatekeypassphrase
|
||||
* -service_account_path /path/to/service-account.json \
|
||||
*/
|
||||
public final class PublishedDevicesCli {
|
||||
private WvPLCASProxyEnvironment environment = null;
|
||||
private PublishedDevicesProvider publishedDevices = null;
|
||||
private String serviceCertPath = null;
|
||||
private String privateKeyPath = null;
|
||||
private String privateKeyPassphrase = null;
|
||||
|
||||
/** Command Line Flags. */
|
||||
static class Flags{
|
||||
private Flags() {}
|
||||
|
||||
@Parameter(names = "-service_cert_path", description = "Path to service certificate")
|
||||
private String serviceCertPath = "";
|
||||
|
||||
@Parameter(names = "-service_private_key_path",
|
||||
description = "Path to private key file needed to decrypt service certificate")
|
||||
private String servicePrivateKeyPath = "";
|
||||
|
||||
@Parameter(names = "-service_private_key_passphrase",
|
||||
description = "Passphrase needed to decrypt the private key")
|
||||
private String servicePrivateKeyPassphrase = "";
|
||||
|
||||
@Parameter(names = "-service_account_path",
|
||||
description = "Path to a GCP Service Account json file")
|
||||
private String serviceAccountPath = "";
|
||||
|
||||
@Parameter(names = "-api_service_path",
|
||||
description = "Optional. Path to a Widevine API service.")
|
||||
private String apiServicePath = "widevine.googleapis.com";
|
||||
|
||||
@Parameter(names = "-s",
|
||||
description = "Save PublishedDevices file path.")
|
||||
private String saveFilePath = null;
|
||||
}
|
||||
|
||||
public PublishedDevicesCli(String serviceCertPath, String privateKeyPath,
|
||||
String privateKeyPassphrase, String serviceAccountPath, String apiServicePath)
|
||||
throws Exception {
|
||||
this.serviceCertPath = serviceCertPath;
|
||||
this.privateKeyPath = privateKeyPath;
|
||||
this.privateKeyPassphrase = privateKeyPassphrase;
|
||||
initializeWvplEnvironment();
|
||||
publishedDevices = new PublishedDevicesProvider(
|
||||
environment, serviceAccountPath, apiServicePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest {@code PublishedDevices} from the Widevine Published Devices Service.
|
||||
*
|
||||
* @return The latest PublishedDevices data.
|
||||
* @throws InterruptedException upon RPC failure.
|
||||
* @throws WvPLStatusException upon WvPLBaseEnvironment errors.
|
||||
*/
|
||||
public PublishedDevices getPublishedDevices() throws InterruptedException, WvPLStatusException {
|
||||
return publishedDevices.getPublishedDevices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves PublishedDevices proto data to a file.
|
||||
*
|
||||
* @param saveFilePath The path to the save file.
|
||||
* @param publishedDevices A PublishedDevices proto.
|
||||
*/
|
||||
public static void savePublishedDevicesDataToFile(String saveFilePath,
|
||||
PublishedDevices publishedDevices) throws IOException {
|
||||
Files.write(
|
||||
Paths.get(saveFilePath),
|
||||
BaseEncoding.base64Url().encode(publishedDevices.toByteArray()).getBytes(UTF_8));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Flags flags = new Flags();
|
||||
new JCommander(flags, args);
|
||||
PublishedDevicesCli devices = new PublishedDevicesCli(
|
||||
flags.serviceCertPath,
|
||||
flags.servicePrivateKeyPath,
|
||||
flags.servicePrivateKeyPassphrase,
|
||||
flags.serviceAccountPath,
|
||||
flags.apiServicePath);
|
||||
PublishedDevices publishedDevices = devices.getPublishedDevices();
|
||||
if (flags.saveFilePath != null) {
|
||||
savePublishedDevicesDataToFile(flags.saveFilePath, publishedDevices);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeWvplEnvironment() throws Exception {
|
||||
environment = new WvPLCASProxyEnvironment(new HashMap<>());
|
||||
// Set service certificate.
|
||||
WvPLStatus status =
|
||||
environment.setServiceCertificate(
|
||||
loadDataFromFile(serviceCertPath),
|
||||
loadDataFromFile(privateKeyPath),
|
||||
privateKeyPassphrase.getBytes(UTF_8));
|
||||
if (!status.getStatusCode().equals(WvPLStatus.StatusCode.OK)) {
|
||||
throw new Exception("Set server certificate status: " + status);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] loadDataFromFile(String filePath) throws IOException {
|
||||
return Files.readAllBytes(Paths.get(filePath));
|
||||
}
|
||||
}
|
||||
369
tools/source/published_devices_delta/WORKSPACE
Normal file
369
tools/source/published_devices_delta/WORKSPACE
Normal file
@@ -0,0 +1,369 @@
|
||||
# JTS Framework WORKSPACE.
|
||||
|
||||
workspace(name = "jts")
|
||||
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository", "git_repository")
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
# In Bazel 2.0, Maven rules provided via new rules_jvm_external.
|
||||
RULES_JVM_EXTERNAL_TAG = "3.1"
|
||||
RULES_JVM_EXTERNAL_SHA = "e246373de2353f3d34d35814947aa8b7d0dd1a58c2f7a6c41cfeaff3007c2d14"
|
||||
http_archive(
|
||||
name = "rules_jvm_external",
|
||||
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
|
||||
sha256 = RULES_JVM_EXTERNAL_SHA,
|
||||
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
|
||||
)
|
||||
load("@rules_jvm_external//:defs.bzl", "maven_install")
|
||||
|
||||
# Google Guice.
|
||||
maven_install(
|
||||
name = "google_guice",
|
||||
artifacts = ["com.google.inject:guice:4.2.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Appache core framework.
|
||||
maven_install(
|
||||
name = "apache_httpcore",
|
||||
artifacts = ["org.apache.httpcomponents:httpcore:4.4.10"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google APIs client library
|
||||
maven_install(
|
||||
name = "google_api",
|
||||
artifacts = ["com.google.api-client:google-api-client:1.30.2"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google HTTP Client
|
||||
maven_install(
|
||||
name = "google_http_client",
|
||||
artifacts = ["com.google.http-client:google-http-client:1.30.2"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google HTTP Client Jackson2 Extensions
|
||||
maven_install(
|
||||
name = "jackson2",
|
||||
artifacts = ["com.google.http-client:google-http-client-jackson2:1.31.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "jackson_core",
|
||||
artifacts = ["com.fasterxml.jackson.core:jackson-core:2.10.0.pr2"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google Oauth2 API
|
||||
maven_install(
|
||||
name = "google_oauth2",
|
||||
artifacts = ["com.google.oauth-client:google-oauth-client:1.30.1"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google Java common framework.
|
||||
maven_install(
|
||||
name = "google_guava",
|
||||
artifacts = ["com.google.guava:guava:25.1-jre"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GRPC
|
||||
git_repository(
|
||||
name = "io_grpc_grpc_java",
|
||||
remote = "https://github.com/grpc/grpc-java.git",
|
||||
tag = "v1.23.0",
|
||||
)
|
||||
|
||||
# GRPC Core
|
||||
maven_install(
|
||||
name = "grpc_core",
|
||||
artifacts = ["io.grpc:grpc-core:1.23.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GRPC Netty
|
||||
maven_install(
|
||||
name = "grpc_netty",
|
||||
artifacts = ["io.grpc:grpc-netty:1.23.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "grpc_netty_all",
|
||||
artifacts = ["io.netty:netty-all:4.1.41.Final"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GRPC Stub
|
||||
maven_install(
|
||||
name = "grpc_stub",
|
||||
artifacts = ["io.grpc:grpc-stub:1.23.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GRPC Contenxt
|
||||
maven_install(
|
||||
name = "grpc_context",
|
||||
artifacts = ["io.grpc:grpc-context:1.18.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# GSON
|
||||
maven_install(
|
||||
name = "gson",
|
||||
artifacts = ["com.google.code.gson:gson:2.8.6"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Netty TcNative (for GRPC)
|
||||
maven_install(
|
||||
name = "netty_tcnative",
|
||||
artifacts = ["io.netty:netty-tcnative:2.0.25.Final"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Netty BoringSSL
|
||||
maven_install(
|
||||
name = "netty_boringssl",
|
||||
artifacts = ["io.netty:netty-tcnative-boringssl-static:2.0.25.Final"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Open Census (for GRPC)
|
||||
maven_install(
|
||||
name = "open_census_api",
|
||||
artifacts = ["io.opencensus:opencensus-api:0.24.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "open_census",
|
||||
artifacts = ["io.opencensus:opencensus-contrib-http-jetty-client:0.19.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "open_census_util",
|
||||
artifacts = ["io.opencensus:opencensus-contrib-http-util:0.19.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
maven_install(
|
||||
name = "open_census_grpc_metrics",
|
||||
artifacts = ["io.opencensus:opencensus-contrib-grpc-metrics:0.24.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Perfmark (GRPC)
|
||||
maven_install(
|
||||
name = "io_perfmark_api",
|
||||
artifacts = ["io.perfmark:perfmark-api:0.17.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Google Protobuf Protos
|
||||
PROTOBUF_BUILD_FILE = """
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
PROTO_FILES = [
|
||||
"google/protobuf/descriptor.proto",
|
||||
]
|
||||
|
||||
filegroup(
|
||||
name = "protobuf_files",
|
||||
srcs = PROTO_FILES,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "protobuf_protos",
|
||||
srcs = [":protobuf_files"],
|
||||
visibility = ["//visibility:public"],
|
||||
|
||||
)
|
||||
"""
|
||||
|
||||
git_repository(
|
||||
name = "com_github_googleapis_googleapis",
|
||||
remote = "https://github.com/googleapis/googleapis.git",
|
||||
branch = "master",
|
||||
)
|
||||
load("@com_github_googleapis_googleapis//:repository_rules.bzl", "switched_rules_by_language")
|
||||
switched_rules_by_language(
|
||||
name = "com_google_googleapis_imports",
|
||||
java = True)
|
||||
|
||||
http_archive(
|
||||
name = "common_protos",
|
||||
build_file_content = PROTOBUF_BUILD_FILE,
|
||||
strip_prefix = "protobuf-3.9.1/src",
|
||||
urls = [
|
||||
"https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protobuf-all-3.9.1.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
# Java commandline framework.
|
||||
maven_install(
|
||||
name = "jcommander",
|
||||
artifacts = ["com.beust:jcommander:1.72"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
#Javax Inject (for Guice).
|
||||
maven_install(
|
||||
name = "javax_inject",
|
||||
artifacts = ["javax.inject:javax.inject:1"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# JSON Java.
|
||||
maven_install(
|
||||
name = "json",
|
||||
artifacts = ["org.json:json:20090211"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# JSR305 Annotations.
|
||||
maven_install(
|
||||
name = "jsr305_annotations",
|
||||
artifacts = ["com.google.code.findbugs:jsr305:3.0.2"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# AOP (for Guice).
|
||||
maven_install(
|
||||
name = "aopalliance",
|
||||
artifacts = ["aopalliance:aopalliance:1.0"],
|
||||
repositories = [
|
||||
"https://jcenter.bintray.com",
|
||||
"https://maven.google.com",
|
||||
"https://repo1.maven.org/maven2",
|
||||
],
|
||||
)
|
||||
|
||||
# Protocol Buffer compiler.
|
||||
git_repository(
|
||||
name = "com_google_protobuf",
|
||||
remote = "https://github.com/google/protobuf.git",
|
||||
tag = "v3.9.1",
|
||||
)
|
||||
|
||||
bind(
|
||||
name = "protobuf",
|
||||
actual = "@com_google_protobuf//:protobuf",
|
||||
)
|
||||
|
||||
bind(
|
||||
name = "protobuf_java",
|
||||
actual = "@com_google_protobuf//:protobuf_java",
|
||||
)
|
||||
|
||||
# Loads necessary bazel rules for later consumption.
|
||||
load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories")
|
||||
grpc_java_repositories()
|
||||
|
||||
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||
protobuf_deps()
|
||||
@@ -0,0 +1,40 @@
|
||||
# Copyright 2019 Google LLC. All rights reserved.
|
||||
|
||||
# Published Devices protocol buffer definitions for the
|
||||
# Widevine Published Devices One Platform API service.
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
|
||||
|
||||
proto_library(
|
||||
name = "published_devices_proto",
|
||||
srcs = ["published_devices.proto"],
|
||||
deps = [
|
||||
":device_security_profiles_proto",
|
||||
"@com_github_googleapis_googleapis//google/api:annotations_proto",
|
||||
"@com_github_googleapis_googleapis//google/api:field_behavior_proto",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "device_security_profiles_proto",
|
||||
srcs = ["device_security_profiles.proto"],
|
||||
deps = [
|
||||
"@com_github_googleapis_googleapis//google/api:field_behavior_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "published_devices_java_proto",
|
||||
deps = [":published_devices_proto"],
|
||||
|
||||
)
|
||||
|
||||
java_grpc_library(
|
||||
name = "published_devices_grpc",
|
||||
srcs = [":published_devices_proto"],
|
||||
deps = [
|
||||
":published_devices_java_proto",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,94 @@
|
||||
// This file contains the proto definitions of DeviceSecurityProfile needed for
|
||||
// the PublishedDevicesService.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.chrome.widevine.contentpartners.v1beta1;
|
||||
|
||||
import "google/api/field_behavior.proto";
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "DeviceSecurityProfilesProto";
|
||||
option java_package = "com.google.chrome.widevine.contentpartners.v1beta1";
|
||||
|
||||
// The DeviceSecurityProfileCriteria is produced by the client (a Widevine
|
||||
// SDK). It is serialized and embedded in the
|
||||
// ListDeviceSecurityProfilesRequest.
|
||||
message DeviceSecurityProfileCriteria {
|
||||
// Content provider who wants to get the DSPs. Required.
|
||||
string content_provider = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
// Content owners who own the DSPs. If this field is empty, return all
|
||||
// DSPs that the content provider is included. Otherwise, a list of DSPs
|
||||
// owned by the listed content_owners would be filtered for the requested
|
||||
// provider. Optional field.
|
||||
repeated string content_owners = 2 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
// A request sent to Widevine Published Server to retrieve
|
||||
// the DeviceSecurityProfiles.
|
||||
// (-- api-linter: core::0132::request-unknown-fields=disabled
|
||||
// api-linter: core::0132::request-parent-required=disabled
|
||||
// api-linter: core::0158::request-page-token-field=disabled
|
||||
// api-linter: core::0158::request-page-size-field=disabled
|
||||
// aip.dev/not-precedent: This is a non-standard, non-precedent API that
|
||||
// cannot use pagination. It has no parent, page_size and page_token.
|
||||
// Pagination is not appropriate. --)
|
||||
message ListDeviceSecurityProfilesRequest {
|
||||
// DeviceSecurityProfileCriteria for List request. Required.
|
||||
DeviceSecurityProfileCriteria device_security_profile_criteria = 1
|
||||
[(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
||||
// A signed message which contains a serialized DeviceSecurityProfileList and
|
||||
// the signature.
|
||||
// (--GOOGLE_INTERNAL
|
||||
// This message is copied from
|
||||
// video/widevine/protos/public/device_security_profile_list.proto
|
||||
// --)
|
||||
message SignedDeviceSecurityProfiles {
|
||||
// Serialized DeviceSecurityProfileList. Required.
|
||||
// A device security profile list contains device security profiles
|
||||
// defined by the content owner. Each DSP aggregates the device's
|
||||
// capabilities, such as security profile level, minimum output requirements,
|
||||
// minimum security requirements for this profile. The information is intended
|
||||
// to be shared publicly.
|
||||
bytes device_security_profiles = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
// Signature of device_security_profiles. Signed with root
|
||||
// certificate private key using RSASSA-PSS. Required.
|
||||
bytes signature = 2 [(google.api.field_behavior) = REQUIRED];
|
||||
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
// A response returned from Widevine Published Server which contains a signed
|
||||
// DeviceSecurityProfileList message.
|
||||
// (-- api-linter: core::0132::response-unknown-fields=disabled
|
||||
// api-linter: core::0158::response-repeated-first-field=disabled
|
||||
// api-linter: core::0158::response-next-page-token-field=disabled
|
||||
// aip.dev/not-precedent: This is a non-standard, non-precedent API that
|
||||
// cannot use pagination. We serialize and sign the list data in a signed
|
||||
// message, which is used in the response. The first field is not repeated
|
||||
// and response has no next_page_token field. The
|
||||
// SignedDeviceSecurityProfiles is intended to be consumed as a single blob.
|
||||
// Pagination is not appropriate. --)
|
||||
message ListDeviceSecurityProfilesResponse {
|
||||
// A signed message which contains a serialized DeviceSecurityProfileList and
|
||||
// the signature.
|
||||
SignedDeviceSecurityProfiles signed_device_security_profiles = 1
|
||||
[(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
||||
// A representation of a hash algorithm used in signature.
|
||||
// (--GOOGLE_INTERNAL
|
||||
// This enum is copied from
|
||||
// video/widevine/protos/public/hash_algorithm.proto
|
||||
// --)
|
||||
enum HashAlgorithm {
|
||||
// Unspecified hash algorithm: SHA_256 shall be used for ECC based algorithms
|
||||
// and SHA_1 shall be used otherwise.
|
||||
HASH_ALGORITHM_UNSPECIFIED = 0;
|
||||
// Secure Hash Algorithm 1 (SHA-1).
|
||||
HASH_ALGORITHM_SHA_1 = 1;
|
||||
// Secure Hash Algorithm 2 256 bits (SHA-256).
|
||||
HASH_ALGORITHM_SHA_256 = 2;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// This file contains the definitions needed for the PublishedDevicesService.
|
||||
// The PublishedDevicesService allows clients to retrieve a signed and
|
||||
// verifiable list of devices and device security profiles that support the
|
||||
// Widevine Digital Rights Management (DRM) solution.
|
||||
//
|
||||
// (--GOOGLE_INTERNAL
|
||||
// This proto is intended to support a feature of the "Widevine API" where
|
||||
// external content providers will retrieve device certificate status list
|
||||
// as well as device secruity profiles to achieve better and more secure
|
||||
// playback experience.
|
||||
//
|
||||
// For more info about the service, please see design doc
|
||||
// https://docs.google.com/document/d/1ZClc0HJuFlijDrdZxcR_DmNOi6Hqo7bjjEtewLnafas/edit?usp=sharing
|
||||
// --)
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package google.chrome.widevine.contentpartners.v1beta1;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/chrome/widevine/contentpartners/v1beta1/device_security_profiles.proto";
|
||||
|
||||
option csharp_namespace = "Google.Chrome.Widevine.ContentPartners.V1Beta1";
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "PublishedDevicesProtos";
|
||||
option java_package = "com.google.chrome.widevine.contentpartners.v1beta1";
|
||||
|
||||
// GCWPD is an acronym for Google Chrome Widevine Published Devices.
|
||||
option objc_class_prefix = "GCWPD";
|
||||
|
||||
|
||||
// This service produces a list of Widevine supported devices
|
||||
// signed by a certificate that can be verified by the client.
|
||||
service PublishedDevicesService {
|
||||
// Return the PublishedDevices containing the list of devices and a signature.
|
||||
// The request is used to authenticate the client.
|
||||
rpc GetPublishedDevices(PublishedDevicesRequest) returns (PublishedDevices) {
|
||||
|
||||
option (google.api.http) = {
|
||||
post: "/v1beta1/publishedDevices:getSignedBatch"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// Return the ListDeviceSecurityProfilesResponse containing a list of
|
||||
// device security profiles.
|
||||
rpc ListDeviceSecurityProfiles(ListDeviceSecurityProfilesRequest)
|
||||
returns (ListDeviceSecurityProfilesResponse) {
|
||||
|
||||
option (google.api.http) = {
|
||||
get: "/v1beta1/deviceSecurityProfiles:listDeviceSecurityProfiles"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// The SdkClientInformation is produced by the client (a Widevine SDK). It is
|
||||
// serialized and embedded in the PublishedDevicesRequest. It is used to
|
||||
// declare attributes of the client's SDK including the Widevine-issued service
|
||||
// certificate that is used by the client.
|
||||
message SdkClientInformation {
|
||||
// The version of sdk. Required.
|
||||
string sdk_version = 1;
|
||||
// POSIX time, in seconds, when this request was created. Required.
|
||||
uint64 sdk_time_seconds = 2;
|
||||
// The serialized service certificate used to sign the request. Required.
|
||||
bytes service_certificate = 3;
|
||||
}
|
||||
|
||||
// A signed request sent to Widevine Provisioning Server (keysmith) to retrieve
|
||||
// the PublishedDevices.
|
||||
message PublishedDevicesRequest {
|
||||
// A serialized SdkClientInformation proto. Required.
|
||||
bytes sdk_client_information = 1;
|
||||
|
||||
// This is the SHA256 digest, PKCS#7 padded signature of the
|
||||
// sdk_client_information field. This signature uses the
|
||||
// RSA private key corresponding to the server certificate. Required.
|
||||
bytes signature = 2;
|
||||
|
||||
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
// Contains a serialized DeviceCertificateStatusList and the signature.
|
||||
message PublishedDevices {
|
||||
// Serialized DeviceCertificateStatusList. Required.
|
||||
// A device certificate status list contains information about various
|
||||
// device series information such as the make, model and status (RELEASED,
|
||||
// IN_TESTING, REVOKED, etc).The information is intended to be shared
|
||||
// publicly.
|
||||
bytes published_devices = 1;
|
||||
|
||||
// Signature of device_certificate_status_list_request. Signed with root
|
||||
// certificate private key using RSASSA-PSS. Required.
|
||||
bytes signature = 2;
|
||||
|
||||
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
41
tools/source/published_devices_delta/tools/BUILD
Normal file
41
tools/source/published_devices_delta/tools/BUILD
Normal file
@@ -0,0 +1,41 @@
|
||||
# Copyright 2019 Google LLC. All rights reserved.
|
||||
# Desciption:
|
||||
# JTS tools.
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
java_library(
|
||||
name = "published_devices_delta_lib",
|
||||
srcs = [
|
||||
"PublishedDevicesDeltaWrapper.java",
|
||||
"PublishedDevicesWrapper.java",
|
||||
],
|
||||
deps = [
|
||||
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_java_proto",
|
||||
"@com_google_protobuf//:protobuf_java",
|
||||
"//video/widevine/protos/public:device_certificate_status_java_proto",
|
||||
"//video/widevine/protos/public:device_certificate_status_proto",
|
||||
"//video/widevine/protos/public:published_devices_delta_java_proto",
|
||||
"//video/widevine/protos/public:published_devices_delta_proto",
|
||||
"@google_guava//:com_google_guava_guava",
|
||||
],
|
||||
)
|
||||
|
||||
java_binary(
|
||||
name = "published_devices_delta",
|
||||
srcs = [
|
||||
"PublishedDevicesMain.java",
|
||||
],
|
||||
main_class = "com.google.video.widevine.jts.tools.PublishedDevicesMain",
|
||||
deps = [
|
||||
":published_devices_delta_lib",
|
||||
"@com_google_protobuf//:protobuf_java",
|
||||
"@jcommander//:com_beust_jcommander",
|
||||
"@json//:org_json_json",
|
||||
"//video/widevine/protos/public:device_certificate_status_java_proto",
|
||||
"//video/widevine/protos/public:device_certificate_status_proto",
|
||||
"//video/widevine/protos/public:published_devices_delta_java_proto",
|
||||
"//video/widevine/protos/public:published_devices_delta_proto",
|
||||
"@google_guava//:com_google_guava_guava",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,250 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved.
|
||||
|
||||
package com.google.video.widevine.jts.tools;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevices;
|
||||
import com.google.protobuf.ExtensionRegistry;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.video.widevine.protos.DeviceCertificateStatusProtos.DeviceCertificateStatus;
|
||||
import com.google.video.widevine.protos.DeviceCertificateStatusProtos.PublishedDevicesList;
|
||||
import com.google.video.widevine.protos.PublishedDevicesDeltaProtos.PublishedDevicesDelta;
|
||||
import com.google.video.widevine.protos.PublishedDevicesDeltaProtos.PublishedDevicesDelta.Header;
|
||||
import com.google.video.widevine.protos.PublishedDevicesDeltaProtos.PublishedDevicesDelta.Modified;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** Published Devices Delta Wrapper class to get {@link PublishedDevicesDelta}. */
|
||||
public final class PublishedDevicesDeltaWrapper {
|
||||
private PublishedDevicesList originalList = null;
|
||||
private PublishedDevicesList newList = null;
|
||||
private PublishedDevicesDelta publishedDevicesDelta = null;
|
||||
private final Map<Integer, DeviceCertificateStatus> dcslAddedMap = new LinkedHashMap<>();
|
||||
private final Map<Integer, DeviceCertificateStatus> dcslRemovedMap = new LinkedHashMap<>();
|
||||
private final Map<Integer, Modified> dcslModifiedMap = new LinkedHashMap<>();
|
||||
static final int MAJOR_VERSION = 1;
|
||||
static final int MINOR_VERSION = 1;
|
||||
static final int RELEASE = 0;
|
||||
|
||||
/**
|
||||
* PublishedDevicesDeltaWrapper constructor. The input is two byte array serialized
|
||||
* PublishedDevices proto.
|
||||
*
|
||||
* @param publishedDevicesInBytes1 first serialized PublishedDevices proto in bytes.
|
||||
* @param publishedDevicesInBytes2 second serialized PublishedDevices proto in bytes.
|
||||
* @throws InvalidProtocolBufferException if failed to parse published devices or if failed to
|
||||
* parse PublishedDevicesList.
|
||||
*/
|
||||
public PublishedDevicesDeltaWrapper(
|
||||
byte[] publishedDevicesInBytes1, byte[] publishedDevicesInBytes2)
|
||||
throws InvalidProtocolBufferException {
|
||||
checkNotNull(publishedDevicesInBytes1, "'publishedDevicesInBytes1' must not be null");
|
||||
checkNotNull(publishedDevicesInBytes2, "'publishedDevicesInBytes2' must not be null");
|
||||
PublishedDevices publishedDevices1 =
|
||||
PublishedDevices.parseFrom(publishedDevicesInBytes1, ExtensionRegistry.getEmptyRegistry());
|
||||
PublishedDevices publishedDevices2 =
|
||||
PublishedDevices.parseFrom(publishedDevicesInBytes2, ExtensionRegistry.getEmptyRegistry());
|
||||
parsePublishedDevicesList(publishedDevices1, publishedDevices2);
|
||||
this.publishedDevicesDelta = createPublishedDevicesDelta(originalList, newList);
|
||||
createPublishedDevicesDeltaInfo(publishedDevicesDelta);
|
||||
}
|
||||
|
||||
/**
|
||||
* PublishedDevicesDeltaWrapper constructor. The input is two PublishedDevices protos.
|
||||
*
|
||||
* @param publishedDevices1 first PublishedDevices proto.
|
||||
* @param publishedDevices2 second PublishedDevices proto.
|
||||
* @throws InvalidProtocolBufferException if failed to parse PublishedDevicesList from published
|
||||
* devices.
|
||||
*/
|
||||
public PublishedDevicesDeltaWrapper(
|
||||
PublishedDevices publishedDevices1, PublishedDevices publishedDevices2)
|
||||
throws InvalidProtocolBufferException {
|
||||
checkNotNull(publishedDevices1, "'publishedDevices1' must not be null");
|
||||
checkNotNull(publishedDevices2, "'publishedDevices2' must not be null");
|
||||
parsePublishedDevicesList(publishedDevices1, publishedDevices2);
|
||||
this.publishedDevicesDelta = createPublishedDevicesDelta(originalList, newList);
|
||||
createPublishedDevicesDeltaInfo(publishedDevicesDelta);
|
||||
}
|
||||
|
||||
/**
|
||||
* PublishedDevicesDeltaWrapper constructor. The input is PublishedDevicesDelta proto.
|
||||
*
|
||||
* @param publishedDevicesDelta PublishedDevicesDeltaWrapper proto.
|
||||
*/
|
||||
public PublishedDevicesDeltaWrapper(PublishedDevicesDelta publishedDevicesDelta) {
|
||||
checkNotNull(publishedDevicesDelta, "'delta' must not be null");
|
||||
this.publishedDevicesDelta = publishedDevicesDelta;
|
||||
createPublishedDevicesDeltaInfo(publishedDevicesDelta);
|
||||
}
|
||||
|
||||
/** Returns {@link PublishedDevicesDelta} of originalPublishedDevices and newPublishedDevices. */
|
||||
public PublishedDevicesDelta getDelta() {
|
||||
return publishedDevicesDelta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link PublishedDevicesDelta} of originalPublishedDevices and newPublishedDevices.
|
||||
*
|
||||
* @param originalList original list in PublishedDevicesList proto
|
||||
* @param newList new list in PublishedDevicesList proto
|
||||
*/
|
||||
static PublishedDevicesDelta createPublishedDevicesDelta(
|
||||
PublishedDevicesList originalList, PublishedDevicesList newList) {
|
||||
// Construct PublishedDevicesDelta.
|
||||
PublishedDevicesDelta.Builder deltaBuilder = PublishedDevicesDelta.newBuilder();
|
||||
// Construct Header object.
|
||||
Header header =
|
||||
Header.newBuilder()
|
||||
.setPrevCreationTimeSeconds(originalList.getCreationTimeSeconds())
|
||||
.setNewCreationTimeSeconds(newList.getCreationTimeSeconds())
|
||||
.build();
|
||||
deltaBuilder.setHeader(header);
|
||||
|
||||
// Add removed, added and modified field in to delta.
|
||||
List<DeviceCertificateStatus> prevDCSL = originalList.getDeviceCertificateStatusList();
|
||||
List<DeviceCertificateStatus> newDcsl = newList.getDeviceCertificateStatusList();
|
||||
Map<Integer, DeviceCertificateStatus> dcslMap = new LinkedHashMap<>();
|
||||
// Add all the original DCSLs into the map.
|
||||
for (DeviceCertificateStatus dcsl : prevDCSL) {
|
||||
dcslMap.put(dcsl.getDeviceInfo().getSystemId(), dcsl);
|
||||
}
|
||||
|
||||
for (DeviceCertificateStatus dcsl : newDcsl) {
|
||||
int systemId = dcsl.getDeviceInfo().getSystemId();
|
||||
if (dcslMap.containsKey(systemId) && !dcsl.equals(dcslMap.get(systemId))) {
|
||||
deltaBuilder.addModifiedBuilder().setPrevDevice(dcslMap.get(systemId)).setNewDevice(dcsl);
|
||||
} else if (!dcslMap.containsKey(systemId)) {
|
||||
// Add the new DCSL into added field in PublishedDevicesDeltaWrapper.
|
||||
deltaBuilder.addAdded(dcsl);
|
||||
}
|
||||
// Remove the iterated DCSL from the map.
|
||||
dcslMap.remove(systemId);
|
||||
}
|
||||
// Add the original DCSL into removed field in PublishedDevicesDeltaWrapper.
|
||||
if (!dcslMap.isEmpty()) {
|
||||
deltaBuilder.addAllRemoved(dcslMap.values());
|
||||
}
|
||||
|
||||
return deltaBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the formatted text output of the {@link PublishedDevicesDelta}.
|
||||
*
|
||||
* @return String String format of publishedDevices.
|
||||
*/
|
||||
public static String toString(PublishedDevicesDelta delta) {
|
||||
return delta.toString();
|
||||
}
|
||||
|
||||
/** Parse {@link PublishedDevicesList} from {@link PublishedDevices}. */
|
||||
private void parsePublishedDevicesList(
|
||||
PublishedDevices publishedDevices1, PublishedDevices publishedDevices2)
|
||||
throws InvalidProtocolBufferException {
|
||||
// Parse PublishedDevicesList proto.
|
||||
originalList =
|
||||
PublishedDevicesList.parseFrom(
|
||||
publishedDevices1.getPublishedDevices(), ExtensionRegistry.getEmptyRegistry());
|
||||
newList =
|
||||
PublishedDevicesList.parseFrom(
|
||||
publishedDevices2.getPublishedDevices(), ExtensionRegistry.getEmptyRegistry());
|
||||
|
||||
// Swap the PublishedDevicesList list if originalList is newer than newList.
|
||||
if (originalList.getCreationTimeSeconds() > newList.getCreationTimeSeconds()) {
|
||||
PublishedDevicesList temp = newList;
|
||||
newList = originalList;
|
||||
originalList = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link DeviceCertificateStatus} of the specific system_id.
|
||||
*
|
||||
* @param systemId Device system_id.
|
||||
* @return DeviceCertificateStatus Returns DeviceCertificateStatus of the specific system_id if it
|
||||
* is added. Otherwise it will return null.
|
||||
*/
|
||||
public DeviceCertificateStatus getAddedDeviceCertificateStatus(int systemId) {
|
||||
return dcslAddedMap.get(systemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link DeviceCertificateStatus} of the specific system_id.
|
||||
*
|
||||
* @param systemId Device system_id.
|
||||
* @return DeviceCertificateStatus Returns the DeviceCertificateStatus of the specific system_id
|
||||
* if it is removed.Otherwise it will return null.
|
||||
*/
|
||||
public DeviceCertificateStatus getRemovedDeviceCertificateStatus(int systemId) {
|
||||
return dcslRemovedMap.get(systemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link Modified} of the specific system_id. Return null if not found.
|
||||
*
|
||||
* @param systemId Device system_id.
|
||||
* @return Modified Returns ModifiedDeviceCertificateStatus of the specific system_id. Return null
|
||||
* if not found.
|
||||
*/
|
||||
public Modified getModifiedDeviceCertificateStatus(int systemId) {
|
||||
return dcslModifiedMap.get(systemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count of added DeviceCertificateStatus in delta.
|
||||
*
|
||||
* @return a list of system_ids for added DeviceCertificateStatus in delta.
|
||||
*/
|
||||
public List<Integer> getAddedDevices() {
|
||||
return new ArrayList<>(dcslAddedMap.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count of modified DeviceCertificateStatus in delta.
|
||||
*
|
||||
* @return a list of system_ids for modified DeviceCertificateStatus in delta.
|
||||
*/
|
||||
public List<Integer> getModifiedDevices() {
|
||||
return new ArrayList<>(dcslRemovedMap.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of system ids for removed DeviceCertificateStatus in delta.
|
||||
*
|
||||
* @return a list of system_ids for removed DeviceCertificateStatus in delta.
|
||||
*/
|
||||
public List<Integer> getRemovedDevices() {
|
||||
return new ArrayList<>(dcslModifiedMap.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of Published Devices Release.
|
||||
*
|
||||
* @return the version of Published Devices Release as a String.
|
||||
*/
|
||||
public String getVersion() {
|
||||
return MAJOR_VERSION + "." + MINOR_VERSION + "." + RELEASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse PublishedDevicesDeltaWrapper to get AddedMap, RemovedMap and ModifiedMap for
|
||||
* PublishedDevicesList.
|
||||
*
|
||||
* @param publishedDevicesDelta PublishedDevicesDelta delta.
|
||||
*/
|
||||
private void createPublishedDevicesDeltaInfo(PublishedDevicesDelta publishedDevicesDelta) {
|
||||
for (DeviceCertificateStatus status : publishedDevicesDelta.getAddedList()) {
|
||||
dcslAddedMap.put(status.getDeviceInfo().getSystemId(), status);
|
||||
}
|
||||
for (DeviceCertificateStatus status : publishedDevicesDelta.getRemovedList()) {
|
||||
dcslRemovedMap.put(status.getDeviceInfo().getSystemId(), status);
|
||||
}
|
||||
for (Modified status : publishedDevicesDelta.getModifiedList()) {
|
||||
dcslModifiedMap.put(status.getPrevDevice().getDeviceInfo().getSystemId(), status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved.
|
||||
package com.google.video.widevine.jts.tools;
|
||||
|
||||
import static com.google.common.io.BaseEncoding.base64;
|
||||
import static com.google.common.io.BaseEncoding.base64Url;
|
||||
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.video.widevine.protos.DeviceCertificateStatusProtos.DeviceCertificateStatus;
|
||||
import com.google.video.widevine.protos.PublishedDevicesDeltaProtos.PublishedDevicesDelta;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Published Devices command line tool.
|
||||
*
|
||||
* <p>Provides a command line tool to get the diff between two PublishedDevices Proto, parse the
|
||||
* PublishedDevices and PublishedDevicesDelta.
|
||||
*
|
||||
* <p>To build: Bazel build tools:published_devices_delta_deploy.jar
|
||||
*
|
||||
* <p>To run: java -jar /path/to/published_devices_lib_deploy.jar -new_published_devices_path path
|
||||
* -original_published_devices_path path -print
|
||||
*
|
||||
* <p>To run: java -jar /path/to/published_devices_lib_deploy.jar -new_published_devices_path path
|
||||
* -original_published_devices_path path -system_id 100 -get_system_ids
|
||||
*
|
||||
* <p>To run: java -jar /path/to/published_devices_lib_deploy.jar -query path -system_id 100
|
||||
*/
|
||||
final class PublishedDevicesMain {
|
||||
private static final Logger logger = Logger.getLogger(PublishedDevicesMain.class.getName());
|
||||
private static final int ZERO_SYSTEM_ID = 0;
|
||||
private static final String JSON_NAME = "signedList";
|
||||
/** Command Line Flags. */
|
||||
static class Flags {
|
||||
private Flags() {}
|
||||
|
||||
@Parameter(
|
||||
names = "-original_published_devices_path",
|
||||
description = "Path to original PublishedDevices file")
|
||||
private String originalPublishedDevicesPath = null;
|
||||
|
||||
@Parameter(
|
||||
names = "-new_published_devices_path",
|
||||
description = "Path to new PublishedDevices file")
|
||||
private String newPublishedDevicesPath = null;
|
||||
|
||||
@Parameter(
|
||||
names = "-print",
|
||||
description =
|
||||
"Setting to true, if content provider want to print the published devices in String.")
|
||||
private boolean print = false;
|
||||
|
||||
@Parameter(names = "-query", description = "Parse published devices file.")
|
||||
private String query = null;
|
||||
|
||||
@Parameter(names = "-system_id", description = "Device system-id.")
|
||||
private int systemId = ZERO_SYSTEM_ID;
|
||||
|
||||
@Parameter(
|
||||
names = "-get_system_ids",
|
||||
description =
|
||||
"Boolean to get list of system_ids in added/removed/modified PublishedDevicesList.")
|
||||
private boolean getSystenIdsList = false;
|
||||
}
|
||||
|
||||
/** Main function to run Published Devices Delta command line tool. */
|
||||
public static void main(String[] args) {
|
||||
Flags flags = new Flags();
|
||||
new JCommander(flags, args);
|
||||
if (flags.newPublishedDevicesPath != null && flags.originalPublishedDevicesPath != null) {
|
||||
parsePublishedDevicesDelta(flags);
|
||||
} else if (flags.query != null) {
|
||||
try {
|
||||
byte[] publishedDevices = getPublishedDevicesAsBytes(flags.query);
|
||||
checkLoadFileResult(flags.query, publishedDevices);
|
||||
PublishedDevicesWrapper wrapper = new PublishedDevicesWrapper(publishedDevices);
|
||||
if (flags.systemId != ZERO_SYSTEM_ID) {
|
||||
DeviceCertificateStatus deviceCertificateStatus =
|
||||
wrapper.getDeviceCertificateStatus(flags.systemId);
|
||||
if (deviceCertificateStatus == null) {
|
||||
logger.log(
|
||||
Level.SEVERE,
|
||||
flags.systemId
|
||||
+ " (system-id) does not found in PublishedDevicesList from "
|
||||
+ flags.query);
|
||||
System.exit(1);
|
||||
}
|
||||
System.out.println(deviceCertificateStatus);
|
||||
// TODO(b/160253740): Add ProvisonedStatus, ProvisionedDeviceInfo and function.
|
||||
}
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
logger.log(
|
||||
Level.SEVERE,
|
||||
"InvalidProtocolBufferException encountered to parse device certificate status list"
|
||||
+ " or published devices proto:"
|
||||
+ e);
|
||||
} catch (IOException e) {
|
||||
logger.log(
|
||||
Level.SEVERE, "IOException encountered trying to open published devices file: " + e);
|
||||
}
|
||||
} else if (flags.originalPublishedDevicesPath != null
|
||||
|| flags.newPublishedDevicesPath != null) {
|
||||
logger.log(
|
||||
Level.SEVERE,
|
||||
"Both originalPublishedDevicesPath and newPublishedDevicesPath should be specified.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse the argument related to PublishedDevicesDelta. */
|
||||
private static void parsePublishedDevicesDelta(Flags flags) {
|
||||
try {
|
||||
byte[] originalPublishedDevices =
|
||||
getPublishedDevicesAsBytes(flags.originalPublishedDevicesPath);
|
||||
byte[] newPublishedDevices = getPublishedDevicesAsBytes(flags.newPublishedDevicesPath);
|
||||
checkLoadFileResult(flags.originalPublishedDevicesPath, originalPublishedDevices);
|
||||
checkLoadFileResult(flags.newPublishedDevicesPath, newPublishedDevices);
|
||||
PublishedDevicesDeltaWrapper devices =
|
||||
new PublishedDevicesDeltaWrapper(originalPublishedDevices, newPublishedDevices);
|
||||
PublishedDevicesDelta delta = devices.getDelta();
|
||||
if (flags.print) {
|
||||
System.out.println(delta);
|
||||
}
|
||||
parseDeltaInfo(devices, flags);
|
||||
} catch (IOException e) {
|
||||
logger.log(
|
||||
Level.SEVERE, "IOException encountered trying to open published devices files: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse the argument related to PublishedDevicesDelta. */
|
||||
private static void parseDeltaInfo(
|
||||
PublishedDevicesDeltaWrapper publishedDevicesDelta, Flags flags) {
|
||||
if (flags.systemId != 0) {
|
||||
if (publishedDevicesDelta.getAddedDeviceCertificateStatus(flags.systemId) != null) {
|
||||
System.out.println(
|
||||
flags.systemId + " system-id is found in added field of published devices delta.");
|
||||
System.out.println(publishedDevicesDelta.getAddedDeviceCertificateStatus(flags.systemId));
|
||||
|
||||
} else if (publishedDevicesDelta.getRemovedDeviceCertificateStatus(flags.systemId) != null) {
|
||||
System.out.println(
|
||||
flags.systemId + " system-id is found in removed field of published devices delta.");
|
||||
System.out.println(publishedDevicesDelta.getRemovedDeviceCertificateStatus(flags.systemId));
|
||||
} else if (publishedDevicesDelta.getModifiedDeviceCertificateStatus(flags.systemId) != null) {
|
||||
System.out.println(
|
||||
flags.systemId + " system-id is found in modified field of published devices delta.");
|
||||
System.out.println(
|
||||
publishedDevicesDelta.getModifiedDeviceCertificateStatus(flags.systemId));
|
||||
} else {
|
||||
logger.log(Level.SEVERE, flags.systemId + "does not found in the PublishedDevicesDelta.");
|
||||
}
|
||||
}
|
||||
if (flags.getSystenIdsList) {
|
||||
System.out.println(
|
||||
"List of system_id for added published devices in published devices delta: "
|
||||
+ publishedDevicesDelta.getAddedDevices());
|
||||
System.out.println(
|
||||
"List of system_id for removed published devices in published devices delta: "
|
||||
+ publishedDevicesDelta.getRemovedDevices());
|
||||
System.out.println(
|
||||
"List of system_id for removed published devices in published devices delta: "
|
||||
+ publishedDevicesDelta.getModifiedDevices());
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkLoadFileResult(String filePath, byte[] result) {
|
||||
if (result == null) {
|
||||
logger.log(Level.SEVERE, "Fail to load the file:" + filePath);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load published devices Json file into string.
|
||||
*
|
||||
* @param filePath file path in String.
|
||||
* @return byte array file content in String.
|
||||
* @throws IOException if failed to read the file.
|
||||
*/
|
||||
public static byte[] getPublishedDevicesAsBytes(String filePath) throws IOException {
|
||||
String result = loadFile(filePath);
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
String requestBody = "";
|
||||
try {
|
||||
// Parse both PublishedDevices v1 output.
|
||||
JSONObject obj = new JSONObject(result);
|
||||
requestBody = obj.getString(JSON_NAME);
|
||||
} catch (JSONException e) {
|
||||
// Parse both PublishedDevices v2 output.
|
||||
requestBody = result;
|
||||
}
|
||||
byte[] serializedDCSL = base64Decode(requestBody);
|
||||
|
||||
return serializedDCSL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load file into string.
|
||||
*
|
||||
* @param filePath file path in String.
|
||||
* @return String file content in String.
|
||||
* @throws IOException if failed to read the file.
|
||||
*/
|
||||
public static String loadFile(String filePath) throws IOException {
|
||||
StringBuilder result = new StringBuilder();
|
||||
List<String> input = Files.readAllLines(Paths.get(filePath));
|
||||
for (String element : input) {
|
||||
result.append(element);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a base64-encoded string or web-safe base64-encoded string.
|
||||
*
|
||||
* @param base64EncodedData base64 encode data in String.
|
||||
* @return byte[] decoded string in byte array.
|
||||
*/
|
||||
public static byte[] base64Decode(String base64EncodedData) {
|
||||
try {
|
||||
return base64().decode(base64EncodedData);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Do nothing. Try the url safe base64 decode next.
|
||||
}
|
||||
return base64Url().decode(base64EncodedData);
|
||||
}
|
||||
|
||||
private PublishedDevicesMain() {}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved.
|
||||
package com.google.video.widevine.jts.tools;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevices;
|
||||
import com.google.protobuf.ExtensionRegistry;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.video.widevine.protos.DeviceCertificateStatusProtos.DeviceCertificateStatus;
|
||||
import com.google.video.widevine.protos.DeviceCertificateStatusProtos.PublishedDevicesList;
|
||||
import com.google.video.widevine.protos.PublishedDevicesDeltaProtos.PublishedDevicesDelta;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/** Wrap the PublishedDevices proto in PublishedDevicesWrapper. */
|
||||
final class PublishedDevicesWrapper {
|
||||
private PublishedDevices publishedDevices = null;
|
||||
private PublishedDevicesList publishedDevicesList = null;
|
||||
private final Map<Integer, DeviceCertificateStatus> dcslMap = new LinkedHashMap<>();
|
||||
|
||||
/** Constructor to create PublishedDevicesWrapper object with {@link PublishedDevices} */
|
||||
public PublishedDevicesWrapper(PublishedDevices publishedDevices)
|
||||
throws InvalidProtocolBufferException {
|
||||
checkNotNull(publishedDevices, "'published devices' must not be null");
|
||||
this.publishedDevices = publishedDevices;
|
||||
parsePublishedDevicesList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to create PublishedDevicesWrapper object with byte array from {@link
|
||||
* PublishedDevices} serialized proto.
|
||||
*/
|
||||
public PublishedDevicesWrapper(byte[] publishedDevicesInfo)
|
||||
throws InvalidProtocolBufferException {
|
||||
checkNotNull(publishedDevicesInfo, "'published devices' must not be null");
|
||||
publishedDevices =
|
||||
PublishedDevices.parseFrom(publishedDevicesInfo, ExtensionRegistry.getEmptyRegistry());
|
||||
parsePublishedDevicesList();
|
||||
}
|
||||
|
||||
private void parsePublishedDevicesList() throws InvalidProtocolBufferException {
|
||||
publishedDevicesList =
|
||||
PublishedDevicesList.parseFrom(
|
||||
publishedDevices.getPublishedDevices(), ExtensionRegistry.getEmptyRegistry());
|
||||
|
||||
// Add all the original DCSLs into the map.
|
||||
for (DeviceCertificateStatus dcsl : publishedDevicesList.getDeviceCertificateStatusList()) {
|
||||
dcslMap.put(dcsl.getDeviceInfo().getSystemId(), dcsl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PublishedDevicesList .
|
||||
*
|
||||
* @return {@link PublishedDevicesList} field in {@link PublishedDevices}.
|
||||
*/
|
||||
public PublishedDevicesList getPublishedDevicesList() {
|
||||
|
||||
return publishedDevicesList;
|
||||
}
|
||||
/**
|
||||
* Get DeviceCertificateStatus for specific systemId.
|
||||
*
|
||||
* @param systemId systemId in Integer.
|
||||
* @return {@link DeviceCertificateStatus} for specific systemId.
|
||||
*/
|
||||
public DeviceCertificateStatus getDeviceCertificateStatus(int systemId) {
|
||||
return dcslMap.get(systemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of PublishedDevicesList.
|
||||
*
|
||||
* @return int Size of PublishedDevicesList.
|
||||
*/
|
||||
public int getSize() {
|
||||
return publishedDevicesList.getDeviceCertificateStatusCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return PublishedDevicesList as a String.
|
||||
*
|
||||
* @return {@link PublishedDevicesList} in String.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return publishedDevicesList.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link PublishedDevicesDelta} by getting delta of new PublishedDevices with current
|
||||
* PublishedDevices.
|
||||
*
|
||||
* @param newPublishedDevices PublishedDevices proto.
|
||||
* @return {@link PublishedDevicesDelta}.
|
||||
* @throws InvalidProtocolBufferException if failed to parse published devices.
|
||||
*/
|
||||
public PublishedDevicesDelta getPublishedDevicesDelta(PublishedDevices newPublishedDevices)
|
||||
throws InvalidProtocolBufferException {
|
||||
PublishedDevicesDeltaWrapper delta =
|
||||
new PublishedDevicesDeltaWrapper(this.publishedDevices, newPublishedDevices);
|
||||
return delta.getDelta();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
# Copyright 2017 Google LLC. All rights reserved.
|
||||
|
||||
# Protocol buffer definitions for Widevine Services License Server SDK.
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
filegroup(
|
||||
name = "wvdrm_binary_release_files",
|
||||
srcs = glob(["**"]),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "wvpl_binary_release_files",
|
||||
srcs = [":exported_wvpl_license_server_sdk_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "exported_wvpl_license_server_sdk_proto",
|
||||
srcs = [
|
||||
"client_identification.proto",
|
||||
"errors.proto",
|
||||
"hash_algorithm.proto",
|
||||
"license_protocol.proto",
|
||||
"license_server_sdk.proto",
|
||||
"provisioned_device_info.proto",
|
||||
"remote_attestation.proto",
|
||||
"sdk_license_data_config.proto",
|
||||
"signed_drm_certificate.proto",
|
||||
"verified_media_pipeline.proto",
|
||||
"widevine_pssh.proto",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "exported_wvdrm_license_server_sdk_proto",
|
||||
srcs = [
|
||||
"client_identification.proto",
|
||||
"device_certificate_status.proto",
|
||||
"drm_certificate.proto",
|
||||
"errors.proto",
|
||||
"hash_algorithm.proto",
|
||||
"license_protocol.proto",
|
||||
"license_server_sdk.proto",
|
||||
"provisioned_device_info.proto",
|
||||
"remote_attestation.proto",
|
||||
"sdk_license_data_config.proto",
|
||||
"signed_drm_certificate.proto",
|
||||
"verified_media_pipeline.proto",
|
||||
"widevine_pssh.proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "exported_wvpl_license_server_sdk_java_proto",
|
||||
deps = [":exported_wvpl_license_server_sdk_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "exported_wvdrm_license_server_sdk_java_proto",
|
||||
deps = [":exported_wvdrm_license_server_sdk_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "client_identification_proto",
|
||||
srcs = ["client_identification.proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "client_identification_cc_proto",
|
||||
deps = [":client_identification_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "client_identification_java_proto",
|
||||
deps = [":client_identification_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "device_certificate_status_proto",
|
||||
srcs = ["device_certificate_status.proto"],
|
||||
deps = [
|
||||
":hash_algorithm_proto",
|
||||
":provisioned_device_info_proto",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "device_common_cc_proto",
|
||||
deps = [":device_common_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "device_common_java_proto",
|
||||
deps = [":device_common_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "device_common_proto",
|
||||
srcs = ["device_common.proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "device_certificate_status_cc_proto",
|
||||
deps = [":device_certificate_status_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "device_certificate_status_java_proto",
|
||||
deps = [":device_certificate_status_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "drm_certificate_proto",
|
||||
srcs = ["drm_certificate.proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "drm_certificate_cc_proto",
|
||||
deps = [":drm_certificate_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "drm_certificate_java_proto",
|
||||
deps = [":drm_certificate_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "errors_proto",
|
||||
srcs = ["errors.proto"],
|
||||
deps = [],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "errors_cc_proto",
|
||||
deps = [":errors_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "errors_java_proto",
|
||||
deps = [":errors_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "license_protocol_proto",
|
||||
srcs = ["license_protocol.proto"],
|
||||
deps = [
|
||||
":client_identification_proto",
|
||||
":drm_certificate_proto",
|
||||
":hash_algorithm_proto",
|
||||
":remote_attestation_proto",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "license_protocol_cc_proto",
|
||||
deps = [":license_protocol_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "license_protocol_java_proto",
|
||||
deps = [":license_protocol_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "license_server_sdk_proto",
|
||||
srcs = ["license_server_sdk.proto"],
|
||||
deps = [
|
||||
":license_protocol_proto",
|
||||
":widevine_pssh_proto",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "license_server_sdk_cc_proto",
|
||||
deps = [":license_server_sdk_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "license_server_sdk_java_proto",
|
||||
deps = [":license_server_sdk_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "provisioned_device_info_proto",
|
||||
srcs = ["provisioned_device_info.proto"],
|
||||
deps = [":device_common_proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "provisioned_device_info_cc_proto",
|
||||
deps = [":provisioned_device_info_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "provisioned_device_info_java_proto",
|
||||
deps = [":provisioned_device_info_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "published_devices_delta_proto",
|
||||
srcs = ["published_devices_delta.proto"],
|
||||
deps = [":device_certificate_status_proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "published_devices_delta_cc_proto",
|
||||
deps = [":published_devices_delta_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "published_devices_delta_java_proto",
|
||||
deps = [":published_devices_delta_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "remote_attestation_proto",
|
||||
srcs = ["remote_attestation.proto"],
|
||||
deps = [":client_identification_proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "remote_attestation_cc_proto",
|
||||
deps = [":remote_attestation_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "remote_attestation_java_proto",
|
||||
deps = [":remote_attestation_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "sdk_license_data_config_proto_base",
|
||||
srcs = ["sdk_license_data_config.proto"],
|
||||
deps = [
|
||||
":license_protocol_proto",
|
||||
":license_server_sdk_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "sdk_license_data_config_java_proto",
|
||||
deps = [":sdk_license_data_config_proto_base"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "signed_drm_certificate_proto",
|
||||
srcs = ["signed_drm_certificate.proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "signed_drm_certificate_java_proto",
|
||||
deps = [":signed_drm_certificate_proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "signed_drm_certificate_cc_proto",
|
||||
deps = [":signed_drm_certificate_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "verified_media_pipeline_proto",
|
||||
srcs = ["verified_media_pipeline.proto"],
|
||||
deps = [":hash_algorithm_proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "verified_media_pipeline_cc_proto",
|
||||
deps = [":verified_media_pipeline_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "widevine_pssh_proto",
|
||||
srcs = ["widevine_pssh.proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "widevine_pssh_cc_proto",
|
||||
deps = [":widevine_pssh_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "widevine_pssh_java_proto",
|
||||
deps = [":widevine_pssh_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "hash_algorithm_proto",
|
||||
srcs = ["hash_algorithm.proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "hash_algorithm_cc_proto",
|
||||
deps = [":hash_algorithm_proto"],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "hash_algorithm_java_proto",
|
||||
deps = [":hash_algorithm_proto"],
|
||||
)
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright 2017 Google LLC. All rights reserved.
|
||||
//
|
||||
// Author: tinskip@google.com (Thomas Inskip)
|
||||
//
|
||||
// Description:
|
||||
// Device certificate status list object definitions.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package video_widevine;
|
||||
|
||||
import "video/widevine/protos/public/hash_algorithm.proto";
|
||||
import "video/widevine/protos/public/provisioned_device_info.proto";
|
||||
|
||||
option java_outer_classname = "DeviceCertificateStatusProtos";
|
||||
option java_package = "com.google.video.widevine.protos";
|
||||
|
||||
// Contains DRM and OEM certificate status and device information for a
|
||||
// specific system ID.
|
||||
// TODO(tinskip): Move this to its own file.
|
||||
message DeviceCertificateStatus {
|
||||
enum DeprecatedStatus {
|
||||
DEPRECATED_VALID = 0;
|
||||
DEPRECATED_REVOKED = 1;
|
||||
}
|
||||
enum Status {
|
||||
STATUS_UNKNOWN = 0;
|
||||
STATUS_IN_TESTING = 10; // Pre-release, active device.
|
||||
STATUS_RELEASED = 20; // Released, active device.
|
||||
STATUS_TEST_ONLY = 30; // Development-only device.
|
||||
STATUS_REVOKED = 40; // Revoked device.
|
||||
}
|
||||
|
||||
message RevokedIdentifiers {
|
||||
// Contains a sorted list of DRM serial numbers that are revoked.
|
||||
repeated bytes revoked_certificate_serial_numbers = 1;
|
||||
// Contains a sorted list of revoked_unique_id_hashes that are revoked.
|
||||
// These identifiers are hash values of the root of trust identifier.
|
||||
// For a keybox, hash = SHA256(KeyboxUniqueID || SecretSauce) where
|
||||
// SecretSauce is a Widevine owned secret. For Provisioning 3.0, hash =
|
||||
// SHA256(X509SerialNumber|| SecretSauce) where SecretSauce is a Widevine
|
||||
// owned secret.
|
||||
repeated bytes revoked_unique_id_hashes = 2;
|
||||
}
|
||||
|
||||
// Serial number of the intermediate DrmCertificate to which this
|
||||
// message refers. Required.
|
||||
optional bytes drm_serial_number = 1;
|
||||
// Status of the certificate. Optional & deprecated in favor of |status|
|
||||
// below.
|
||||
optional DeprecatedStatus deprecated_status = 2 [default = DEPRECATED_VALID];
|
||||
// Device model information about the device to which the intermediate
|
||||
// certificate(s) correspond.
|
||||
optional ProvisionedDeviceInfo device_info = 4;
|
||||
// Serial number of the OEM X.509 intermediate certificate for this type
|
||||
// of device. Present only if the device is OEM-provisioned.
|
||||
optional bytes oem_serial_number = 5;
|
||||
// Status of the device. Optional.
|
||||
optional Status status = 6 [default = STATUS_UNKNOWN];
|
||||
|
||||
// RevokedIdentifiers collect all the serial_numbers or unique_id_hashes used
|
||||
// for individual drm certificate revocation.
|
||||
optional RevokedIdentifiers revoked_identifiers = 7;
|
||||
}
|
||||
|
||||
// List of DeviceCertificateStatus. Used to propagate certificate revocation
|
||||
// status and device information.
|
||||
message DeviceCertificateStatusList {
|
||||
// POSIX time, in seconds, when the list was created. Required.
|
||||
optional uint32 creation_time_seconds = 1;
|
||||
// DeviceCertificateStatus for each system ID.
|
||||
repeated DeviceCertificateStatus certificate_status = 2;
|
||||
}
|
||||
|
||||
// List of DeviceCertificateStatus. Used to propagate certificate revocation
|
||||
// status and device information. (Used in published devices library)
|
||||
message PublishedDevicesList {
|
||||
// POSIX time, in seconds, when the list was created. Required.
|
||||
optional uint32 creation_time_seconds = 1;
|
||||
// DeviceCertificateStatus for each system ID.
|
||||
repeated DeviceCertificateStatus device_certificate_status = 2;
|
||||
}
|
||||
|
||||
// Signed CertificateStatusList
|
||||
message SignedDeviceCertificateStatusList {
|
||||
// Serialized DeviceCertificateStatusList. Required.
|
||||
optional bytes certificate_status_list = 1;
|
||||
// Signature of certificate_status_list. Signed with root certificate private
|
||||
// key using RSASSA-PSS. Required.
|
||||
optional bytes signature = 2;
|
||||
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||
optional HashAlgorithmProto hash_algorithm = 3;
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved.
|
||||
//
|
||||
// This file contains device-related definitions that are common to both the
|
||||
// legacy device management service and the new devices service. Eventually,
|
||||
// we may merge the contents of this file into other files.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package video_widevine;
|
||||
|
||||
option java_package = "com.google.video.widevine.protos";
|
||||
|
||||
// MOE:begin_strip
|
||||
// See http://go/go-api-flag.
|
||||
// MOE:end_strip
|
||||
|
||||
// Allows additional make/models to be associated with a system_id.
|
||||
message DeviceModel {
|
||||
// ModelStatus is used to specify how confident we are that this
|
||||
// make/model/year combination is allowed by the device manufacturer.
|
||||
// VERIFIED indicates that the manufacturer confirmed that it is correct.
|
||||
// UNVERIFIED means that we have sufficient data to believe it is correct,
|
||||
// but the manufacturer has not confirmed.
|
||||
// UNKNOWN indicates that we do not have sufficient information to indicate
|
||||
// whether or not the device is allowed by the manufacturer.
|
||||
// REJECTED indicates that the manufacturer explicitly disallowed the use
|
||||
// of the make/model/year combination.
|
||||
enum ModelStatus {
|
||||
MODEL_STATUS_UNSPECIFIED = 0;
|
||||
MODEL_STATUS_VERIFIED = 1;
|
||||
MODEL_STATUS_UNVERIFIED = 2;
|
||||
MODEL_STATUS_UNKNOWN = 4;
|
||||
MODEL_STATUS_REJECTED = 3;
|
||||
}
|
||||
// Represents the device manufacturer. Typically, this will be Philips, LG,
|
||||
// Sharp, etc.
|
||||
string manufacturer = 1;
|
||||
// Model of the device.
|
||||
string model_name = 2;
|
||||
// The expected release year of the make/model combination. Optional.
|
||||
uint32 model_year = 3;
|
||||
// The model status of this make and model.
|
||||
ModelStatus status = 4;
|
||||
}
|
||||
|
||||
// DeviceState defines the current state of the device. It is used in
|
||||
// licensing to determine if a (classic or MDRM/CENC) license should be
|
||||
// issued. The status affects if and how a device record is shown in
|
||||
// keysmith's CertificateStatusList.
|
||||
//
|
||||
// States:
|
||||
// DEVICE_STATE_UNKNOWN: This should not be used.
|
||||
// It only indicates that a state has not been set.
|
||||
// IN_TESTING: The first valid state of a device record. A newly created
|
||||
// device should be in this state until the device is considered
|
||||
// "released". In this state a device should only be supported on test
|
||||
// services (e.g. UAT license service).
|
||||
// PRE_RELEASE: The state of a device when it's ready to be used with
|
||||
// production services. In this state a device can receive production
|
||||
// classic and MDRM/CENC licenses. The device will also be listed in
|
||||
// keysmith's certificate status list. The device data will be
|
||||
// available for sharing with internal partners only.
|
||||
// RELEASED: Indicates that the device is available on the store shelves.
|
||||
// The device data will be available for sharing with external partners.
|
||||
// DELETED: Indicates that the device was manually disabled and should
|
||||
// not be used for any test or production services. The device should
|
||||
// not appear in the device certificate status list. Customers will
|
||||
// not be able to see or utilize this state when managing their devices.
|
||||
// TEST_ONLY: Indicates that this device was never intended for production
|
||||
// but can be used for test purposes. The device will be listed in the
|
||||
// certificate status list as a test device.
|
||||
// REVOKED: Indicates that the device was revoked. No test or production
|
||||
// service should honor requests (classic nor MDRM/CENC) from one of
|
||||
// these devices. The device serial number and its REVOKED status will
|
||||
// appear in keysmith's certificate status list.
|
||||
//
|
||||
// Devices in the above states have the following behaviors in widevince
|
||||
// services:
|
||||
//
|
||||
// Licensing | Certificate | Cert | Cert | Test |
|
||||
// State Prod | UAT | Provisioning | Listed | status | device | redact
|
||||
// -- -- -- -- -- -- -- --
|
||||
// IN_TESTING No Yes Yes Yes VALID true yes
|
||||
// TEST_ONLY No Yes Yes Yes VALID true no
|
||||
// PRE_RELEASE Yes Yes Yes Yes VALID false yes
|
||||
// RELEASED Yes Yes Yes Yes VALID false no
|
||||
// REVOKED No No No Yes REVOKED false no
|
||||
// DELETED No No No No n/a n/a n/a
|
||||
enum DeviceState {
|
||||
DEVICE_STATE_UNKNOWN = 0;
|
||||
IN_TESTING = 1;
|
||||
RELEASED = 2;
|
||||
DELETED = 3;
|
||||
TEST_ONLY = 4;
|
||||
REVOKED = 5;
|
||||
PRE_RELEASE = 6;
|
||||
}
|
||||
|
||||
// Specifies the device type, or form factor of a device.
|
||||
enum DeviceType {
|
||||
DEVICE_TYPE_UNSPECIFIED = 0;
|
||||
DEVICE_TYPE_PHONE = 1;
|
||||
DEVICE_TYPE_TV = 2;
|
||||
DEVICE_TYPE_TABLET = 3;
|
||||
DEVICE_TYPE_GAMING_CONSOLE = 4;
|
||||
DEVICE_TYPE_SET_TOP_BOX = 5;
|
||||
DEVICE_TYPE_VIDEO_DONGLE = 6;
|
||||
DEVICE_TYPE_PC = 7;
|
||||
DEVICE_TYPE_AUTO = 8;
|
||||
DEVICE_TYPE_WEARABLE = 9;
|
||||
DEVICE_TYPE_CONNECTED_AUDIO_DEVICE = 10;
|
||||
DEVICE_TYPE_SMART_DISPLAY = 11;
|
||||
// Legacy identifier for records that were created for SoC integration.
|
||||
DEVICE_TYPE_SOC = 12;
|
||||
}
|
||||
|
||||
// Specifies the platform and OS of the device.
|
||||
enum Platform {
|
||||
PLATFORM_UNSPECIFIED = 0;
|
||||
PLATFORM_CHROMECAST = 1;
|
||||
PLATFORM_FUCHSIA = 2;
|
||||
PLATFORM_IOS = 3;
|
||||
PLATFORM_IPAD_OS = 4;
|
||||
PLATFORM_TV_OS = 5;
|
||||
PLATFORM_ANDROID = 6;
|
||||
PLATFORM_WINDOWS = 7;
|
||||
PLATFORM_CHROME_OS = 8;
|
||||
PLATFORM_MAC_OS = 9;
|
||||
PLATFORM_LINUX = 10;
|
||||
PLATFORM_WEB_OS = 11;
|
||||
PLATFORM_TIZEN = 12;
|
||||
PLATFORM_FIRE_OS = 13;
|
||||
PLATFORM_ROKU = 14;
|
||||
PLATFORM_PLAYSTATION = 15;
|
||||
PLATFORM_XBOX = 16;
|
||||
PLATFORM_KAIOS = 17;
|
||||
PLATFORM_RDK = 18;
|
||||
PLATFORM_OTHER = 19;
|
||||
}
|
||||
|
||||
// This is used for tri-state answers. Yes-TEE, Yes-REE, No.
|
||||
// This has to be in device_common to avoid import conflicts between security
|
||||
// profiles and device security profiles.
|
||||
enum OsOptionalSupport {
|
||||
OS_OPTIONAL_SUPPORT_UNSPECIFIED = 0;
|
||||
YES_TEE = 1;
|
||||
YES_REE = 2;
|
||||
NO_SUPPORT = 3;
|
||||
}
|
||||
|
||||
// Version of High-bandwidth Digital Content Protection (HDCP).
|
||||
// This has to be in device_common to avoid import conflicts between security
|
||||
// profiles and device security profiles.
|
||||
enum HdcpVersion {
|
||||
HDCP_VERSION_UNSPECIFIED = 0;
|
||||
HDCP_V1 = 1;
|
||||
HDCP_V2 = 2;
|
||||
HDCP_V2_1 = 3;
|
||||
HDCP_V2_2 = 4;
|
||||
HDCP_V2_3 = 5;
|
||||
}
|
||||
|
||||
// Widevine device security level.
|
||||
enum DeviceSecurityLevel {
|
||||
SECURITY_LEVEL_UNSPECIFIED = 0;
|
||||
LEVEL_1 = 1;
|
||||
LEVEL_2 = 2;
|
||||
LEVEL_3 = 3;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package video_widevine;
|
||||
|
||||
// LINT.IfChange
|
||||
enum HashAlgorithmProto {
|
||||
// Unspecified hash algorithm: SHA_256 shall be used for ECC based algorithms
|
||||
// and SHA_1 shall be used otherwise.
|
||||
HASH_ALGORITHM_UNSPECIFIED = 0;
|
||||
HASH_ALGORITHM_SHA_1 = 1;
|
||||
HASH_ALGORITHM_SHA_256 = 2;
|
||||
}
|
||||
// LINT.ThenChange(//depot/google3/google/chrome/widevine/contentpartners/v1beta1/device_security_profiles.proto)
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2016 Google LLC. All rights reserved.
|
||||
|
||||
// Description:
|
||||
// Provisioned device info format definitions.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package video_widevine;
|
||||
|
||||
import "video/widevine/protos/public/device_common.proto";
|
||||
|
||||
option java_package = "com.google.video.widevine.protos";
|
||||
option java_outer_classname = "ProvisionedDeviceInfoProto";
|
||||
|
||||
// MOE:begin_strip
|
||||
// See http://go/go-api-flag.
|
||||
// MOE:end_strip
|
||||
|
||||
// Contains device model information for a provisioned device.
|
||||
message ProvisionedDeviceInfo {
|
||||
enum WvSecurityLevel {
|
||||
// Defined in Widevine Security Integration Guide for DASH on Android:
|
||||
// http://doc/1Zum-fcJeoIw6KG1kDP_KepIE5h9gAZg0PaMtemBvk9c/edit#heading=h.1t3h5sf
|
||||
LEVEL_UNSPECIFIED = 0;
|
||||
LEVEL_1 = 1;
|
||||
LEVEL_2 = 2;
|
||||
LEVEL_3 = 3;
|
||||
}
|
||||
// Widevine initial provisioning / bootstrapping method. DRM certificates are
|
||||
// required for retrieving licenses, so if a DRM certificate is not initially
|
||||
// provisioned, then the provisioned credentials will be used to provision
|
||||
// a DRM certificate via the Widevine Provisioning Service.
|
||||
enum ProvisioningMethod {
|
||||
// Don't use this.
|
||||
PROVISIONING_METHOD_UNSPECIFIED = 0;
|
||||
// Factory-provisioned device-unique keybox.
|
||||
FACTORY_KEYBOX = 1;
|
||||
// Factory-provisioned device-unique OEM certificate.
|
||||
FACTORY_OEM_DEVICE_CERTIFICATE = 2;
|
||||
// Factory-provisioned model-group OEM certificate.
|
||||
FACTORY_OEM_GROUP_CERTIFICATE = 3;
|
||||
// Factory-provisioned model-group DRM certificate (Level-3 "baked in").
|
||||
FACTORY_DRM_GROUP_CERTIFICATE = 4;
|
||||
// OTA-provisioned keybox (Level-1 ARC++).
|
||||
OTA_KEYBOX = 5;
|
||||
// OTA-provisioned device-unique OEM certificate.
|
||||
OTA_OEM_DEVICE_CERTIFICATE = 6;
|
||||
// OTA-provisioned model-group OEM certificate.
|
||||
OTA_OEM_GROUP_CERTIFICATE = 7;
|
||||
// OTA-provisioned device-unique DRM certificate (Bedrock).
|
||||
OTA_DRM_DEVICE_CERTIFICATE = 8;
|
||||
// OTA-provisioned device-unique OEM certificate (Beanstalk).
|
||||
OTA_OEM_DEVICE_CERTIFICATE_SIGMA_210 = 9;
|
||||
}
|
||||
|
||||
// Widevine system ID for the device. Mandatory.
|
||||
optional uint32 system_id = 1;
|
||||
// Name of system-on-a-chip. Optional.
|
||||
optional string soc = 2;
|
||||
// First registered manufacturer. Optional.
|
||||
optional string manufacturer = 3;
|
||||
// First registered manufacturer's model name. Matches "brand" in device
|
||||
// metadata. Optional.
|
||||
optional string model = 4;
|
||||
// First registered type of device (Phone, Tablet, TV, etc).
|
||||
optional string device_type = 5;
|
||||
// First registered device model year. Optional.
|
||||
optional uint32 model_year = 6;
|
||||
// Widevine-defined security level. Optional.
|
||||
optional WvSecurityLevel security_level = 7 [default = LEVEL_UNSPECIFIED];
|
||||
// True if the certificate corresponds to a test (non production) device.
|
||||
// Optional.
|
||||
optional bool test_device = 8 [default = false];
|
||||
// Indicates the type of device root of trust which was factory provisioned.
|
||||
optional ProvisioningMethod provisioning_method = 9;
|
||||
// A list of ModelInfo using the same system_id.
|
||||
repeated DeviceModel model_info = 10;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved.
|
||||
//
|
||||
// Description:
|
||||
// PublishedDevicesDelta object definitions.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package video_widevine;
|
||||
|
||||
import "video/widevine/protos/public/device_certificate_status.proto";
|
||||
|
||||
option java_outer_classname = "PublishedDevicesDeltaProtos";
|
||||
option java_package = "com.google.video.widevine.protos";
|
||||
|
||||
// Contains lists of DeviceCertificateStatus for added or removed or modified
|
||||
// devices. Used to find delta of two PublishedDevices.
|
||||
message PublishedDevicesDelta {
|
||||
message Header {
|
||||
optional uint32 prev_creation_time_seconds = 1;
|
||||
optional uint32 new_creation_time_seconds = 2;
|
||||
}
|
||||
|
||||
message Modified {
|
||||
optional DeviceCertificateStatus prev_device = 1;
|
||||
optional DeviceCertificateStatus new_device = 2;
|
||||
}
|
||||
|
||||
// POSIX time, in seconds, show the delta of creation_time_seconds. Optional.
|
||||
optional Header header = 1;
|
||||
// List of added DeviceCertificateStatus.
|
||||
repeated DeviceCertificateStatus added = 2;
|
||||
// List of removed DeviceCertificateStatus.
|
||||
repeated DeviceCertificateStatus removed = 3;
|
||||
// List of modified DeviceCertificateStatus.
|
||||
repeated Modified modified = 4;
|
||||
}
|
||||
Reference in New Issue
Block a user