Add entitlement support for offline and migrate WORKSPACE

This commit is contained in:
Jacob Trimble
2025-01-17 23:55:54 +00:00
parent 77a33b906a
commit 5da305d9de
30 changed files with 253 additions and 320 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,5 @@
bazel-* bazel-*
MODULE.bazel* MODULE.bazel.lock
.DS_Store .DS_Store
infra/config/.recipe_deps/ infra/config/.recipe_deps/
*__pycache__/ *__pycache__/

View File

@@ -1 +1 @@
build --cxxopt='-std=c++17' build --enable_bzlmod --cxxopt='-std=c++17'

0
whitebox-impl/BUILD Normal file
View File

View File

@@ -0,0 +1,28 @@
# Copyright 2025 Google LLC. All Rights Reserved.
module(name = "whitebox_api_intertrust")
bazel_dep(name = "whitebox")
local_path_override(
module_name = "whitebox",
path = "../whitebox",
)
# Add the repo a second time since "chromium_deps" is a separate dependency.
# See @whitebox//:MODULE.bazel for reasons.
bazel_dep(name = "chromium_deps")
local_path_override(
module_name = "chromium_deps",
path = "../whitebox/chromium_deps",
)
git_override(
module_name = "odk",
build_file = "//:odk.BUILD",
patches = ["//:odk.patch"],
patch_args = ["-p1"],
commit = "7b5fec3a7929cb36cf53db216565b09c99dc2c85", # 19.2
remote = "https://widevine-partner.googlesource.com/oemcrypto_core_message.git",
)

View File

@@ -1,107 +0,0 @@
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
local_repository(
name = "whitebox_api",
path = "../whitebox",
)
git_repository(
name = "glog_repo",
commit = "3ba8976592274bc1f907c402ce22558011d6fc5e", # 2020-02-16
remote = "https://github.com/google/glog.git",
)
git_repository(
name = "com_github_gflags_gflags",
commit = "2e227c3daae2ea8899f49858a23f3d318ea39b57", # 2020-01-15
remote = "https://github.com/gflags/gflags.git",
)
git_repository(
name = "abseil_repo",
commit = "fcb104594b0bb4b8ac306cb2f55ecdad40974683", # 2018-12-04
remote = "https://github.com/abseil/abseil-cpp.git",
)
git_repository(
name = "boringssl_repo",
commit = "d345d68d5c4b5471290ebe13f090f1fd5b7e8f58", # 2022-09-14
remote = "https://github.com/google/boringssl.git",
)
git_repository(
name = "googletest_repo",
commit = "b796f7d44681514f58a683a3a71ff17c94edb0c1", # 2023-01-17
remote = "https://github.com/google/googletest.git",
)
# We use "com_google_protobuf" instead of "protobuf_repo" because Bazel's proto
# rules implicitly depend on @com_google_protobuf. See
# https://bazel.build/blog/2017/02/27/protocol-buffers.html.
git_repository(
name = "com_google_protobuf",
remote = "https://github.com/google/protobuf.git",
tag = "v3.8.0",
)
# bazel_skylib is required by google protobuf.
git_repository(
name = "bazel_skylib",
remote = "https://github.com/bazelbuild/bazel-skylib.git",
tag = "1.0.2",
)
# Protobuf library support. Not included in the recent protobuf release.
http_archive(
name = "zlib",
build_file = "@com_google_protobuf//:third_party/zlib.BUILD",
sha256 = "ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e",
strip_prefix = "zlib-1.3",
urls = ["https://zlib.net/zlib-1.3.tar.gz"],
)
# ODK
new_git_repository(
name = "odk_repo",
build_file = "@whitebox_api//external:odk.BUILD",
commit = "2bfd670424232fbff4e38f25d06cb28ee4c88b61", # 17.1
remote = "https://widevine-partner.googlesource.com/oemcrypto_core_message.git",
repo_mapping = {"@whitebox" : "@whitebox_api"}
)
bind(
name = "glog",
actual = "@glog_repo//:glog",
)
bind(
name = "gflags",
actual = "@com_github_gflags_gflags//:gflags",
)
bind(
name = "boringssl",
actual = "@boringssl_repo//:crypto",
)
bind(
name = "gtest",
actual = "@googletest_repo//:gtest",
)
bind(
name = "gtest_main",
actual = "@googletest_repo//:gtest_main",
)
bind(
name = "protobuf",
actual = "@com_google_protobuf//:protobuf",
)
bind(
name = "odk",
actual = "@odk_repo//:odk",
)

View File

@@ -30,3 +30,8 @@ cc_library(
name = "uat_license_whitebox", name = "uat_license_whitebox",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
cc_library(
name = "license_whitebox_provider_keys_test_data",
visibility = ["//visibility:public"],
)

View File

@@ -63,7 +63,7 @@ cc_library(
], ],
deps = [ deps = [
":core", ":core",
"@whitebox//odk_deps", "@chromium_deps//cdm/protos",
], ],
) )

8
whitebox-impl/odk.patch Normal file
View File

@@ -0,0 +1,8 @@
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..21ba670
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,2 @@
+module(name = "odk")
+bazel_dep(name = "chromium_deps")

View File

@@ -26,7 +26,7 @@ cc_test(
name = "aead_whitebox_test", name = "aead_whitebox_test",
size = "small", size = "small",
deps = [ deps = [
"@whitebox_api//api:aead_whitebox_test", "@whitebox//api:aead_whitebox_test",
"//impl:test_aead_whitebox", "//impl:test_aead_whitebox",
], ],
) )
@@ -35,7 +35,7 @@ cc_test(
name = "aead_whitebox_benchmark", name = "aead_whitebox_benchmark",
size = "small", size = "small",
deps = [ deps = [
"@whitebox_api//api:aead_whitebox_benchmark", "@whitebox//api:aead_whitebox_benchmark",
"//impl:test_aead_whitebox", "//impl:test_aead_whitebox",
], ],
) )
@@ -48,7 +48,7 @@ cc_test(
name = "license_whitebox_test", name = "license_whitebox_test",
size = "small", size = "small",
deps = [ deps = [
"@whitebox_api//api:license_whitebox_test", "@whitebox//api:license_whitebox_test",
"//impl:general_license_whitebox", "//impl:general_license_whitebox",
], ],
) )
@@ -57,7 +57,7 @@ cc_test(
name = "remote_attestation_and_verification_test", name = "remote_attestation_and_verification_test",
size = "small", size = "small",
deps = [ deps = [
"@whitebox_api//api:remote_attestation_and_verification_test", "@whitebox//api:remote_attestation_and_verification_test",
"//impl:general_license_whitebox", "//impl:general_license_whitebox",
], ],
) )
@@ -66,7 +66,7 @@ cc_test(
name = "license_whitebox_benchmark", name = "license_whitebox_benchmark",
size = "small", size = "small",
deps = [ deps = [
"@whitebox_api//api:license_whitebox_benchmark", "@whitebox//api:license_whitebox_benchmark",
"//impl:general_license_whitebox", "//impl:general_license_whitebox",
], ],
) )
@@ -75,7 +75,7 @@ cc_test(
name = "license_whitebox_uat_test", name = "license_whitebox_uat_test",
size = "small", size = "small",
deps = [ deps = [
"@whitebox_api//api:license_whitebox_uat_test", "@whitebox//api:license_whitebox_uat_test",
"//impl:uat_license_whitebox", "//impl:uat_license_whitebox",
], ],
) )
@@ -88,8 +88,8 @@ cc_binary(
name = "license_whitebox_main", name = "license_whitebox_main",
testonly = True, testonly = True,
deps = [ deps = [
"@whitebox_api//api:license_whitebox_main", "@whitebox//api:license_whitebox_main",
"//impl:test_license_whitebox", "//impl:general_license_whitebox",
"//impl:license_whitebox_provider_keys_test_data" "//impl:license_whitebox_provider_keys_test_data"
], ],
) )

View File

@@ -1 +1 @@
build --cxxopt='-std=c++17' build --enable_bzlmod --cxxopt='-std=c++17'

31
whitebox/MODULE.bazel Normal file
View File

@@ -0,0 +1,31 @@
# Copyright 2025 Google LLC. All Rights Reserved.
module(name = "whitebox")
bazel_dep(name = "abseil-cpp", version = "20240722.0.bcr.2")
bazel_dep(name = "boringssl", version = "0.20241209.0")
bazel_dep(name = "gflags", version = "2.2.2")
bazel_dep(name = "glog", version = "0.7.1")
bazel_dep(name = "googletest", version = "1.15.2")
bazel_dep(name = "protobuf", version = "29.2")
# The ODK library depends on proto files in the "chromium_deps" folder. Since
# this would create a circular dependency, this creates a new module for it.
bazel_dep(name = "chromium_deps")
local_path_override(
module_name = "chromium_deps",
path = "chromium_deps",
)
bazel_dep(name = "odk")
git_override(
module_name = "odk",
build_file = "//:odk.BUILD",
commit = "7b5fec3a7929cb36cf53db216565b09c99dc2c85", # 19.2
remote = "https://widevine-partner.googlesource.com/oemcrypto_core_message.git",
# Patch the ODK repo to add a MODULE.bazel file. Bazel adds a field for
# WORKSPACE files, but we need to patch for MODULE.bazel.
patches = ["//:odk.patch"],
patch_args = ["-p1"],
)

View File

@@ -1,105 +0,0 @@
# Copyright 2020 Google LLC. All Rights Reserved.
workspace(name = "whitebox")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
git_repository(
name = "glog_repo",
commit = "3ba8976592274bc1f907c402ce22558011d6fc5e", # 2020-02-16
remote = "https://github.com/google/glog.git",
)
git_repository(
name = "com_github_gflags_gflags",
commit = "2e227c3daae2ea8899f49858a23f3d318ea39b57", # 2020-01-15
remote = "https://github.com/gflags/gflags.git",
)
git_repository(
name = "abseil_repo",
commit = "fcb104594b0bb4b8ac306cb2f55ecdad40974683", # 2018-12-04
remote = "https://github.com/abseil/abseil-cpp.git",
)
git_repository(
name = "boringssl_repo",
commit = "d345d68d5c4b5471290ebe13f090f1fd5b7e8f58", # 2022-09-14
remote = "https://github.com/google/boringssl.git",
)
git_repository(
name = "googletest_repo",
commit = "b796f7d44681514f58a683a3a71ff17c94edb0c1", # 2023-01-17
remote = "https://github.com/google/googletest.git",
)
# We use "com_google_protobuf" instead of "protobuf_repo" because Bazel's proto
# rules implicitly depend on @com_google_protobuf. See
# https://bazel.build/blog/2017/02/27/protocol-buffers.html.
git_repository(
name = "com_google_protobuf",
remote = "https://github.com/google/protobuf.git",
tag = "v3.8.0",
)
# bazel_skylib is required by google protobuf.
git_repository(
name = "bazel_skylib",
remote = "https://github.com/bazelbuild/bazel-skylib.git",
tag = "1.0.2",
)
# Protobuf library support. Not included in the recent protobuf release.
http_archive(
name = "zlib",
build_file = "@com_google_protobuf//:third_party/zlib.BUILD",
sha256 = "9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23",
strip_prefix = "zlib-1.3.1",
urls = ["https://zlib.net/zlib-1.3.1.tar.gz"],
)
# ODK
new_git_repository(
name = "odk_repo",
build_file = "//external:odk.BUILD",
commit = "7b5fec3a7929cb36cf53db216565b09c99dc2c85", # 19.2
remote = "https://widevine-partner.googlesource.com/oemcrypto_core_message.git",
)
bind(
name = "glog",
actual = "@glog_repo//:glog",
)
bind(
name = "gflags",
actual = "@com_github_gflags_gflags//:gflags",
)
bind(
name = "boringssl",
actual = "@boringssl_repo//:crypto",
)
bind(
name = "gtest",
actual = "@googletest_repo//:gtest",
)
bind(
name = "gtest_main",
actual = "@googletest_repo//:gtest_main",
)
bind(
name = "protobuf",
actual = "@com_google_protobuf//:protobuf",
)
bind(
name = "odk",
actual = "@odk_repo//:odk",
)

View File

@@ -215,7 +215,7 @@ cc_library(
"//chromium_deps/cdm/protos", "//chromium_deps/cdm/protos",
"//crypto_utils:aes_cbc_encryptor", "//crypto_utils:aes_cbc_encryptor",
"//crypto_utils:crypto_util", "//crypto_utils:crypto_util",
"//external:odk", "@odk//:odk",
], ],
) )
@@ -410,7 +410,7 @@ cc_library(
":license_whitebox_provider_keys_test_data", ":license_whitebox_provider_keys_test_data",
":test_license_builder", ":test_license_builder",
"//chromium_deps/base:glog", "//chromium_deps/base:glog",
"//external:gflags", "@gflags//:gflags",
], ],
alwayslink = True, alwayslink = True,
) )

View File

@@ -3,6 +3,7 @@
#include "api/license_whitebox.h" #include "api/license_whitebox.h"
#include <string> #include <string>
#include <tuple>
#include <vector> #include <vector>
#include "api/golden_data.h" #include "api/golden_data.h"
@@ -15,7 +16,7 @@ namespace widevine {
class LicenseWhiteboxEntitlementContentKeyTest class LicenseWhiteboxEntitlementContentKeyTest
: public LicenseWhiteboxTestBase, : public LicenseWhiteboxTestBase,
public ::testing::WithParamInterface<size_t> { public ::testing::WithParamInterface<std::tuple<bool, size_t>> {
protected: protected:
void SetUp() { void SetUp() {
LicenseWhiteboxTestBase::SetUp(); LicenseWhiteboxTestBase::SetUp();
@@ -29,6 +30,30 @@ class LicenseWhiteboxEntitlementContentKeyTest
builder.AddEntitlementKey( builder.AddEntitlementKey(
golden_data_.EntitlementContent().entitlement_key); golden_data_.EntitlementContent().entitlement_key);
builder.Build(*server_, &license_); builder.Build(*server_, &license_);
const auto is_offline = std::get<0>(GetParam());
const auto provider_key_id = std::get<1>(GetParam());
auto result = WB_License_ProcessLicenseResponse(
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
license_.core_message.size(), license_.message.data(),
license_.message.size(), license_.signature.data(),
license_.signature.size(), license_.session_key.data(),
license_.session_key.size(), provider_key_id, license_.request.data(),
license_.request.size());
#ifndef HAS_PROVIDER_KEYS
if (provider_key_id != kNoProviderKeyId) {
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
GTEST_SKIP();
}
#endif
#ifndef HAS_ENTITLEMENT
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
#else
ASSERT_EQ(result, WB_RESULT_OK);
if (is_offline) {
ASSERT_NO_FATAL_FAILURE(RecreateOffline());
}
#endif
} }
std::unique_ptr<TestServer> server_; std::unique_ptr<TestServer> server_;
@@ -36,29 +61,9 @@ class LicenseWhiteboxEntitlementContentKeyTest
}; };
TEST_P(LicenseWhiteboxEntitlementContentKeyTest, Decrypt) { TEST_P(LicenseWhiteboxEntitlementContentKeyTest, Decrypt) {
int provider_key_id = GetParam();
auto result = WB_License_ProcessLicenseResponse(
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
license_.core_message.size(), license_.message.data(),
license_.message.size(), license_.signature.data(),
license_.signature.size(), license_.session_key.data(),
license_.session_key.size(), provider_key_id, license_.request.data(),
license_.request.size());
#ifndef HAS_PROVIDER_KEYS
if (provider_key_id != kNoProviderKeyId) {
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
GTEST_SKIP();
}
#endif
#ifndef HAS_ENTITLEMENT
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
#else
ASSERT_EQ(result, WB_RESULT_OK);
#endif
const KeyId key_id = golden_data_.GetFreeId(); const KeyId key_id = golden_data_.GetFreeId();
auto& content = golden_data_.EntitlementContent(); auto& content = golden_data_.EntitlementContent();
result = WB_License_LoadEntitledContentKey( auto result = WB_License_LoadEntitledContentKey(
whitebox_, content.entitlement_key.id.data(), whitebox_, content.entitlement_key.id.data(),
content.entitlement_key.id.size(), key_id.data(), key_id.size(), content.entitlement_key.id.size(), key_id.data(), key_id.size(),
content.key_data_iv.data(), content.key_data_iv.size(), content.key_data_iv.data(), content.key_data_iv.size(),
@@ -85,23 +90,10 @@ TEST_P(LicenseWhiteboxEntitlementContentKeyTest, Decrypt) {
#endif #endif
} }
TEST_F(LicenseWhiteboxEntitlementContentKeyTest, Remove) { TEST_P(LicenseWhiteboxEntitlementContentKeyTest, Remove) {
auto result = WB_License_ProcessLicenseResponse(
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
license_.core_message.size(), license_.message.data(),
license_.message.size(), license_.signature.data(),
license_.signature.size(), license_.session_key.data(),
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
license_.request.size());
#ifndef HAS_ENTITLEMENT
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
#else
ASSERT_EQ(result, WB_RESULT_OK);
#endif
const KeyId key_id = golden_data_.GetFreeId(); const KeyId key_id = golden_data_.GetFreeId();
auto& content = golden_data_.EntitlementContent(); auto& content = golden_data_.EntitlementContent();
result = WB_License_LoadEntitledContentKey( auto result = WB_License_LoadEntitledContentKey(
whitebox_, content.entitlement_key.id.data(), whitebox_, content.entitlement_key.id.data(),
content.entitlement_key.id.size(), key_id.data(), key_id.size(), content.entitlement_key.id.size(), key_id.data(), key_id.size(),
content.key_data_iv.data(), content.key_data_iv.size(), content.key_data_iv.data(), content.key_data_iv.size(),
@@ -135,5 +127,12 @@ TEST_F(LicenseWhiteboxEntitlementContentKeyTest, Remove) {
INSTANTIATE_TEST_SUITE_P(WithAndWithoutProviderKeyId, INSTANTIATE_TEST_SUITE_P(WithAndWithoutProviderKeyId,
LicenseWhiteboxEntitlementContentKeyTest, LicenseWhiteboxEntitlementContentKeyTest,
::testing::Values(kNoProviderKeyId, kProviderKeyId)); ::testing::Combine(::testing::Values(false),
::testing::Values(kNoProviderKeyId,
kProviderKeyId)));
INSTANTIATE_TEST_SUITE_P(
Offline,
LicenseWhiteboxEntitlementContentKeyTest,
::testing::Combine(::testing::Values(true),
::testing::Values(kNoProviderKeyId)));
} // namespace widevine } // namespace widevine

View File

@@ -0,0 +1,3 @@
# Copyright 2025 Google LLC. All Rights Reserved.
module(name = "chromium_deps")
bazel_dep(name = "protobuf", version = "29.2")

View File

@@ -10,7 +10,7 @@ cc_library(
strip_include_prefix = "//chromium_deps", strip_include_prefix = "//chromium_deps",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//external:gflags", "@gflags//:gflags",
"//external:glog", "@glog//:glog",
], ],
) )

View File

@@ -3,10 +3,10 @@
# Protocol buffer definitions for Widevine Services. # Protocol buffer definitions for Widevine Services.
package(default_visibility = ["//visibility:public"]) package(default_visibility = ["//visibility:public"])
load("@com_google_protobuf//:protobuf.bzl", "cc_proto_library") load("@protobuf//bazel:proto_library.bzl", "proto_library")
cc_proto_library( proto_library(
name = "protos", name = "protos_lib",
srcs = [ srcs = [
"certificate_provisioning.proto", "certificate_provisioning.proto",
"client_identification.proto", "client_identification.proto",
@@ -17,7 +17,11 @@ cc_proto_library(
"remote_attestation.proto", "remote_attestation.proto",
"root_of_trust_id.proto", "root_of_trust_id.proto",
], ],
include = ".", strip_import_prefix = "",
default_runtime = "@com_google_protobuf//:protobuf",
protoc = "@com_google_protobuf//:protoc",
) )
cc_proto_library(
name = "protos",
deps = [":protos_lib"],
)

View File

@@ -13,6 +13,9 @@ import "drm_certificate.proto";
import "dtcp_usage.proto"; import "dtcp_usage.proto";
import "hash_algorithm.proto"; import "hash_algorithm.proto";
import "remote_attestation.proto"; import "remote_attestation.proto";
// Because the Android repo combines the two protobufs, we need to export this
// as part of our API.
import public "certificate_provisioning.proto";
option optimize_for = LITE_RUNTIME; option optimize_for = LITE_RUNTIME;

View File

@@ -6,7 +6,7 @@ cc_library(
deps = [ deps = [
"//chromium_deps/testing/include/gmock", "//chromium_deps/testing/include/gmock",
"//chromium_deps/testing/include/gtest", "//chromium_deps/testing/include/gtest",
"//external:gtest", "@googletest//:gtest",
"//external:gtest_main", "@googletest//:gtest_main",
], ],
) )

View File

@@ -22,6 +22,6 @@ cc_library(
strip_include_prefix = "//chromium_deps", strip_include_prefix = "//chromium_deps",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//external:boringssl", "@boringssl//:crypto",
], ],
) )

View File

@@ -90,7 +90,7 @@ cc_test(
deps = [ deps = [
":crypto_util", ":crypto_util",
"//chromium_deps/testing", "//chromium_deps/testing",
"@abseil_repo//absl/strings", "@abseil-cpp//absl/strings",
], ],
) )
@@ -209,6 +209,6 @@ cc_test(
deps = [ deps = [
":sha_util", ":sha_util",
"//chromium_deps/testing", "//chromium_deps/testing",
"@abseil_repo//absl/strings", "@abseil-cpp//absl/strings",
], ],
) )

View File

@@ -31,6 +31,9 @@ inline const BIGNUM* RSA_get0_e(const RSA* r) {
inline const BIGNUM* RSA_get0_n(const RSA* r) { inline const BIGNUM* RSA_get0_n(const RSA* r) {
return r->n; return r->n;
} }
inline const BIGNUM* RSA_get0_d(const RSA* r) {
return r->d;
}
#endif #endif
namespace widevine { namespace widevine {

View File

@@ -285,7 +285,7 @@ TEST_F(RsaUtilTest, ConvertToEulerTotient_NewKey_Success) {
EXPECT_EQ(1, RSA_check_key(private_key.get())); EXPECT_EQ(1, RSA_check_key(private_key.get()));
// If the values are different, break. // If the values are different, break.
if (BN_cmp(private_key->d, rsa->d) != 0) { if (BN_cmp(RSA_get0_d(private_key.get()), RSA_get0_d(rsa.get())) != 0) {
found_distinct_keys = true; found_distinct_keys = true;
break; break;
} }

View File

@@ -1,2 +0,0 @@
# An empty BUILD file. This is needed for the "*.BUILD" files to be loaded by
# bazel.

76
whitebox/odk.BUILD Normal file
View File

@@ -0,0 +1,76 @@
# Copyright 2020 Google LLC. All Rights Reserved.
package(default_visibility = ["//visibility:public"])
filegroup(
name = "odk_common_hdrs",
srcs = [
"oemcrypto/odk/src/odk_serialize.h",
"oemcrypto/odk/src/odk_structs_priv.h",
"oemcrypto/odk/src/serialization_base.h",
],
)
cc_library(
name = "core",
srcs = [
"oemcrypto/odk/src/odk.c",
"oemcrypto/odk/src/odk_assert.h",
"oemcrypto/odk/src/odk_endian.h",
"oemcrypto/odk/src/odk_message.c",
"oemcrypto/odk/src/odk_message_priv.h",
"oemcrypto/odk/src/odk_overflow.c",
"oemcrypto/odk/src/odk_overflow.h",
"oemcrypto/odk/src/odk_serialize.c",
"oemcrypto/odk/src/odk_timer.c",
"oemcrypto/odk/src/odk_util.c",
"oemcrypto/odk/src/odk_util.h",
"oemcrypto/odk/src/serialization_base.c",
":odk_common_hdrs",
],
hdrs = [
"oemcrypto/odk/include/core_message_features.h",
"oemcrypto/odk/include/OEMCryptoCENCCommon.h",
"oemcrypto/odk/include/odk.h",
"oemcrypto/odk/include/odk_attributes.h",
"oemcrypto/odk/include/odk_message.h",
"oemcrypto/odk/include/odk_structs.h",
"oemcrypto/odk/include/odk_target.h",
],
copts = ["-std=c99 -Wno-array-parameter"],
includes = [
"oemcrypto/odk/include",
],
)
cc_library(
name = "serialization",
srcs = [
"oemcrypto/odk/src/core_message_deserialize.cpp",
"oemcrypto/odk/src/core_message_features.cpp",
"oemcrypto/odk/src/core_message_serialize.cpp",
"oemcrypto/odk/src/core_message_serialize_proto.cpp",
":odk_common_hdrs",
],
hdrs = [
"oemcrypto/odk/include/core_message_deserialize.h",
"oemcrypto/odk/include/core_message_serialize.h",
"oemcrypto/odk/include/core_message_serialize_proto.h",
"oemcrypto/odk/include/core_message_types.h",
],
includes = [
"oemcrypto/odk/include",
],
deps = [
":core",
"@chromium_deps//cdm/protos",
],
)
cc_library(
name = "odk",
deps = [
":core",
":serialization",
],
)

8
whitebox/odk.patch Normal file
View File

@@ -0,0 +1,8 @@
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..21ba670
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,2 @@
+module(name = "odk")
+bazel_dep(name = "chromium_deps")

View File

@@ -1,12 +0,0 @@
# Copyright 2020 Google LLC. All Rights Reserved.
package(default_visibility = ["//visibility:public"])
cc_library(
name = "odk_deps",
hdrs = ["license_protocol.pb.h"],
strip_include_prefix = "//odk_deps/",
deps = [
"//chromium_deps/cdm/protos",
],
)

View File

@@ -1,11 +0,0 @@
// Copyright 2020 Google LLC. All Rights Reserved.
#ifndef ODK_DEPS_LICENSE_PROTOCOL_PB_H_
#define ODK_DEPS_LICENSE_PROTOCOL_PB_H_
// Because the Android repo combines the two protobufs, we need to include both
// of them in this header so that the ODK code can find it.
#include "chromium_deps/cdm/protos/certificate_provisioning.pb.h"
#include "chromium_deps/cdm/protos/license_protocol.pb.h"
#endif // ODK_DEPS_LICENSE_PROTOCOL_PB_H_

View File

@@ -31,7 +31,7 @@ cc_library(
"//api:result", "//api:result",
"//api:shared_settings", "//api:shared_settings",
"//chromium_deps/base:glog", "//chromium_deps/base:glog",
"//external:odk", "@odk//:odk",
], ],
) )

View File

@@ -120,6 +120,7 @@ struct WB_License_ExportedData {
bool has_renewal; bool has_renewal;
std::array<uint8_t, 32> renewal_client; std::array<uint8_t, 32> renewal_client;
size_t num_content_keys; size_t num_content_keys;
size_t num_entitlement_keys;
size_t num_generic_keys; size_t num_generic_keys;
WB_License_ExportedData_Key keys[0]; WB_License_ExportedData_Key keys[0];
}; };
@@ -409,9 +410,10 @@ WB_Result WB_CONCAT_VERSION(WB_License_Import)(
DVLOG(1) << "Unsupported version of exported data."; DVLOG(1) << "Unsupported version of exported data.";
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
const size_t total_keys = info->num_content_keys +
info->num_entitlement_keys + info->num_generic_keys;
if (buffer_size < sizeof(WB_License_ExportedData) + if (buffer_size < sizeof(WB_License_ExportedData) +
(sizeof(WB_License_ExportedData_Key) * (sizeof(WB_License_ExportedData_Key) * total_keys)) {
(info->num_content_keys + info->num_generic_keys))) {
DVLOG(1) << "Invalid parameter: Buffer too small."; DVLOG(1) << "Invalid parameter: Buffer too small.";
return WB_RESULT_BUFFER_TOO_SMALL; return WB_RESULT_BUFFER_TOO_SMALL;
} }
@@ -426,20 +428,17 @@ WB_Result WB_CONCAT_VERSION(WB_License_Import)(
(*whitebox)->renewal_key = std::move(renewal_key); (*whitebox)->renewal_key = std::move(renewal_key);
} }
for (size_t i = 0; i < info->num_content_keys; i++) { for (size_t i = 0; i < total_keys; i++) {
auto& key = info->keys[i]; auto& key = info->keys[i];
CHECK(key.key_id_size <= sizeof(key.key_id)); CHECK(key.key_id_size <= sizeof(key.key_id));
std::string key_id{key.key_id.begin(), key.key_id.data() + key.key_id_size};
std::string key_id{key.key_id.begin(), if (i < info->num_content_keys) {
key.key_id.begin() + key.key_id_size}; (*whitebox)->content_keys.emplace(key_id, key.key);
(*whitebox)->content_keys.emplace(key_id, key.key); } else if (i - info->num_content_keys < info->num_entitlement_keys) {
} (*whitebox)->entitlement_keys.emplace(key_id, key.key);
for (size_t i = 0; i < info->num_generic_keys; i++) { } else {
const auto& key = info->keys[info->num_content_keys + i]; (*whitebox)->generic_keys.emplace(key_id, key.key);
CHECK(key.key_id_size <= sizeof(key.key_id)); }
std::string key_id{key.key_id.data(), key.key_id.data() + key.key_id_size};
(*whitebox)->generic_keys.emplace(key_id, key.key);
} }
return WB_RESULT_OK; return WB_RESULT_OK;
@@ -471,7 +470,8 @@ WB_Result WB_CONCAT_VERSION(WB_License_ExportKeys)(
const size_t required_size = const size_t required_size =
sizeof(WB_License_ExportedData) + sizeof(WB_License_ExportedData) +
sizeof(WB_License_ExportedData_Key) * sizeof(WB_License_ExportedData_Key) *
(whitebox->content_keys.size() + whitebox->generic_keys.size()); (whitebox->content_keys.size() + whitebox->entitlement_keys.size() +
whitebox->generic_keys.size());
if (!CheckAndUpdateSize(required_size, buffer_size) || !buffer) { if (!CheckAndUpdateSize(required_size, buffer_size) || !buffer) {
return WB_RESULT_BUFFER_TOO_SMALL; return WB_RESULT_BUFFER_TOO_SMALL;
} }
@@ -485,9 +485,11 @@ WB_Result WB_CONCAT_VERSION(WB_License_ExportKeys)(
} }
info->version = kExportedVersion; info->version = kExportedVersion;
info->num_content_keys = whitebox->content_keys.size(); info->num_content_keys = whitebox->content_keys.size();
info->num_entitlement_keys = whitebox->entitlement_keys.size();
info->num_generic_keys = whitebox->generic_keys.size(); info->num_generic_keys = whitebox->generic_keys.size();
size_t i = 0; size_t i = 0;
for (const auto& dict : {whitebox->content_keys, whitebox->generic_keys}) { for (const auto& dict : {whitebox->content_keys, whitebox->entitlement_keys,
whitebox->generic_keys}) {
for (const auto& pair : dict) { for (const auto& pair : dict) {
auto& key = info->keys[i]; auto& key = info->keys[i];
CHECK(pair.first.size() <= sizeof(key.key_id)); CHECK(pair.first.size() <= sizeof(key.key_id));