Update ODK to v17.1
This commit is contained in:
@@ -1,7 +1,19 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
|
||||
// CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
|
||||
// DEPENDING ON IT IN YOUR PROJECT. ***
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "vendor_widevine_license"
|
||||
// to get the below license kinds:
|
||||
// legacy_by_exception_only (by exception only)
|
||||
default_applicable_licenses: ["vendor_widevine_license"],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "odk_fuzz_library_defaults",
|
||||
srcs: [
|
||||
@@ -165,4 +177,4 @@ cc_fuzz {
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -9,6 +9,18 @@
|
||||
// ----------------------------------------------------------------
|
||||
// Builds libwv_odk.so, The ODK shared Library (libwv_odk) is used
|
||||
// by the OEMCrypto unit tests to generate corpus for ODK fuzz scrips.
|
||||
// *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
|
||||
// CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
|
||||
// DEPENDING ON IT IN YOUR PROJECT. ***
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "vendor_widevine_license"
|
||||
// to get the below license kinds:
|
||||
// legacy_by_exception_only (by exception only)
|
||||
default_applicable_licenses: ["vendor_widevine_license"],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libwv_odk_corpus_generator",
|
||||
include_dirs: [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// We must define this macro to get RTLD_NEXT definition from <dlfcn.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#include "fuzzing/corpus_generator/odk_corpus_generator_helper.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#ifndef WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
# source code may only be used and distributed under the Widevine Master License
|
||||
# source code may only be used and distributed under the Widevine License
|
||||
# Agreement.
|
||||
|
||||
# Reference Link explaining flags for LD_PRELOAD: https://catonmat.net/simple-ld-preload-tutorial-part-two
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
# source code may only be used and distributed under the Widevine Master License
|
||||
# source code may only be used and distributed under the Widevine License
|
||||
# Agreement.
|
||||
|
||||
#TODO(b/151858867): Fix File paths
|
||||
@@ -18,6 +18,10 @@
|
||||
'../src',
|
||||
'../kdo/include',
|
||||
],
|
||||
'cflags': [
|
||||
# TODO(b/172518513): Remove this
|
||||
'-Wno-error=cast-qual',
|
||||
],
|
||||
'cflags_cc': [
|
||||
'-std=c++11',
|
||||
'-g3',
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "odk.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
using features::CoreMessageFeatures;
|
||||
|
||||
bool convert_byte_to_valid_boolean(const bool* in) {
|
||||
const char* buf = reinterpret_cast<const char*>(in);
|
||||
@@ -67,8 +70,8 @@ OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message,
|
||||
return ODK_ParseLicense(message, SIZE_MAX, core_message_length,
|
||||
static_cast<bool>(a->initial_license_load),
|
||||
static_cast<bool>(a->usage_entry_present),
|
||||
a->request_hash, &a->timer_limits, &a->clock_values,
|
||||
nonce_values, parsed_lic);
|
||||
&a->timer_limits, &a->clock_values, nonce_values,
|
||||
parsed_lic);
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_deserialize_RenewalResponse(
|
||||
@@ -122,7 +125,8 @@ bool kdo_serialize_LicenseResponse(const ODK_ParseLicense_Args* args,
|
||||
std::string core_request_sha_256(
|
||||
reinterpret_cast<const char*>(args->request_hash), ODK_SHA256_HASH_SIZE);
|
||||
return serialize::CreateCoreLicenseResponse(
|
||||
parsed_lic, core_request, core_request_sha_256, oemcrypto_core_message);
|
||||
CoreMessageFeatures::kDefaultFeatures, parsed_lic, core_request,
|
||||
core_request_sha_256, oemcrypto_core_message);
|
||||
}
|
||||
|
||||
bool kdo_serialize_RenewalResponse(
|
||||
@@ -134,7 +138,8 @@ bool kdo_serialize_RenewalResponse(
|
||||
nonce_values.api_minor_version, nonce_values.api_major_version,
|
||||
nonce_values.nonce, nonce_values.session_id, renewal_msg.playback_time};
|
||||
return serialize::CreateCoreRenewalResponse(
|
||||
core_request, args->timer_limits.initial_renewal_duration_seconds,
|
||||
CoreMessageFeatures::kDefaultFeatures, core_request,
|
||||
args->timer_limits.initial_renewal_duration_seconds,
|
||||
oemcrypto_core_message);
|
||||
}
|
||||
|
||||
@@ -151,7 +156,8 @@ bool kdo_serialize_ProvisioningResponse(
|
||||
nonce_values.nonce, nonce_values.session_id,
|
||||
std::string(reinterpret_cast<const char*>(args->device_id),
|
||||
args->device_id_length)};
|
||||
return serialize::CreateCoreProvisioningResponse(parsed_prov, core_request,
|
||||
oemcrypto_core_message);
|
||||
return serialize::CreateCoreProvisioningResponse(
|
||||
CoreMessageFeatures::kDefaultFeatures, parsed_prov, core_request,
|
||||
oemcrypto_core_message);
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#ifndef WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "core_message_features.h"
|
||||
#include "core_message_serialize.h"
|
||||
#include "fuzzing/odk_fuzz_structs.h"
|
||||
#include "odk_attributes.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#ifndef WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
#include "odk_attributes.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
// The custom mutator: Ensure that each input can be deserialized properly
|
||||
// by ODK function after mutation.
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
|
||||
size_t max_size, unsigned int seed) {
|
||||
size_t max_size,
|
||||
unsigned int seed UNUSED) {
|
||||
const size_t kProvisioningResponseArgsSize =
|
||||
sizeof(ODK_ParseProvisioning_Args);
|
||||
if (size < kProvisioningResponseArgsSize) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
#include "odk_attributes.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
// The custom mutator: Ensure that each input can be deserialized properly
|
||||
// by ODK function after mutation.
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
|
||||
size_t max_size, unsigned int seed) {
|
||||
size_t max_size,
|
||||
unsigned int seed UNUSED) {
|
||||
const size_t kRenewalResponseArgsSize = sizeof(ODK_ParseRenewal_Args);
|
||||
if (size < kRenewalResponseArgsSize) {
|
||||
return 0;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "odk.h"
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "odk.h"
|
||||
|
||||
#include <endian.h> // TODO(b/147944591): use this one? Or odk_endian.h?
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "core_message_deserialize.h"
|
||||
#include "core_message_features.h"
|
||||
#include "core_message_serialize.h"
|
||||
#include "core_message_types.h"
|
||||
#include "gtest/gtest.h"
|
||||
@@ -28,6 +28,10 @@ using oemcrypto_core_message::ODK_RenewalRequest;
|
||||
using oemcrypto_core_message::deserialize::CoreLicenseRequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::CoreRenewalRequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::
|
||||
CoreRenewedProvisioningRequestFromMessage;
|
||||
|
||||
using oemcrypto_core_message::features::CoreMessageFeatures;
|
||||
|
||||
using oemcrypto_core_message::serialize::CreateCoreLicenseResponse;
|
||||
using oemcrypto_core_message::serialize::CreateCoreProvisioningResponse;
|
||||
@@ -39,12 +43,22 @@ constexpr uint32_t kExtraPayloadSize = 128u;
|
||||
* version number, and we will expect the response to have another version
|
||||
* number. */
|
||||
struct VersionParameters {
|
||||
uint32_t maximum_major_version;
|
||||
uint16_t request_major_version;
|
||||
uint16_t request_minor_version;
|
||||
uint16_t response_major_version;
|
||||
uint16_t response_minor_version;
|
||||
};
|
||||
|
||||
// This function is called by GTest when a parameterized test fails in order
|
||||
// to log the parameter used for the failing test.
|
||||
void PrintTo(const VersionParameters& p, std::ostream* os) {
|
||||
*os << "max=v" << p.maximum_major_version << ", request = v"
|
||||
<< p.request_major_version << "." << p.request_minor_version
|
||||
<< ", response = v" << p.response_major_version << "."
|
||||
<< p.response_minor_version;
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename G>
|
||||
void ValidateRequest(uint32_t message_type,
|
||||
const std::vector<ODK_Field>& extra_fields,
|
||||
@@ -144,11 +158,14 @@ void ValidateResponse(const VersionParameters& versions,
|
||||
&bytes_read, extra_fields));
|
||||
|
||||
// Parse buf with odk
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, odk_parse_func(buf, buf_size));
|
||||
const OEMCryptoResult parse_result = odk_parse_func(buf, buf_size);
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, parse_result);
|
||||
|
||||
size_t size_out = 0;
|
||||
ODK_IterFields(ODK_FieldMode::ODK_DUMP, buf, buf_size, &size_out,
|
||||
extra_fields);
|
||||
if (parse_result != OEMCrypto_SUCCESS) {
|
||||
ODK_IterFields(ODK_FieldMode::ODK_DUMP, buf, buf_size, &size_out,
|
||||
extra_fields);
|
||||
}
|
||||
|
||||
// serialize odk output to oemcrypto_core_message
|
||||
std::string oemcrypto_core_message;
|
||||
@@ -189,15 +206,15 @@ TEST(OdkTest, SerializeFieldsStress) {
|
||||
std::srand(0);
|
||||
size_t total_size = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
fields[i].type = static_cast<ODK_FieldType>(std::rand() %
|
||||
static_cast<int>(ODK_NUMTYPES));
|
||||
fields[i].type = static_cast<ODK_FieldType>(
|
||||
std::rand() % static_cast<int>(ODK_LAST_STRESSABLE_TYPE));
|
||||
fields[i].value = malloc(ODK_AllocSize(fields[i].type));
|
||||
fields[i].name = "stress";
|
||||
total_size += ODK_FieldLength(fields[i].type);
|
||||
}
|
||||
|
||||
uint8_t* buf = new uint8_t[total_size]{};
|
||||
for (int i = 0; i < total_size; i++) {
|
||||
for (size_t i = 0; i < total_size; i++) {
|
||||
buf[i] = std::rand() & 0xff;
|
||||
}
|
||||
|
||||
@@ -256,13 +273,41 @@ TEST(OdkTest, NullRequestTest) {
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length,
|
||||
&nonce_values, nullptr, 0uL));
|
||||
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
nullptr, 0uL, &core_message_length, nullptr, nullptr, 0uL,
|
||||
OEMCrypto_RenewalACert, nullptr, 0uL));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
nullptr, 0uL, nullptr, &nonce_values, nullptr, 0uL,
|
||||
OEMCrypto_RenewalACert, nullptr, 0uL));
|
||||
|
||||
// Null device id in renewed provisioning request is ok
|
||||
uint8_t renewed_message[ODK_RENEWED_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
uint8_t renewal_data[ODK_KEYBOX_RENEWAL_DATA_SIZE] = {0};
|
||||
uint32_t renewal_data_length = ODK_KEYBOX_RENEWAL_DATA_SIZE;
|
||||
core_message_length = ODK_RENEWED_PROVISIONING_REQUEST_SIZE;
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
renewed_message, ODK_RENEWED_PROVISIONING_REQUEST_SIZE,
|
||||
&core_message_length, &nonce_values, nullptr, 0uL,
|
||||
OEMCrypto_RenewalACert, renewal_data, renewal_data_length));
|
||||
|
||||
// Null renewal data in renewed provisioning request is ok
|
||||
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
|
||||
uint32_t device_id_length = ODK_DEVICE_ID_LEN_MAX;
|
||||
core_message_length = ODK_RENEWED_PROVISIONING_REQUEST_SIZE;
|
||||
ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
renewed_message, ODK_RENEWED_PROVISIONING_REQUEST_SIZE,
|
||||
&core_message_length, &nonce_values, device_id, device_id_length,
|
||||
OEMCrypto_RenewalACert, nullptr, 0uL);
|
||||
}
|
||||
|
||||
TEST(OdkTest, NullResponseTest) {
|
||||
constexpr size_t message_size = 64;
|
||||
uint8_t message[message_size] = {0};
|
||||
size_t core_message_length = message_size;
|
||||
uint8_t request_hash[ODK_SHA256_HASH_SIZE] = {0};
|
||||
ODK_TimerLimits timer_limits;
|
||||
ODK_ParsedLicense parsed_license;
|
||||
ODK_NonceValues nonce_values;
|
||||
@@ -271,30 +316,26 @@ TEST(OdkTest, NullResponseTest) {
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
|
||||
// Assert that nullptr does not cause a core dump.
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true,
|
||||
true, request_hash, &timer_limits, &clock_values,
|
||||
&nonce_values, nullptr));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true,
|
||||
true, request_hash, &timer_limits, &clock_values,
|
||||
nullptr, &parsed_license));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true,
|
||||
true, request_hash, &timer_limits, nullptr,
|
||||
&nonce_values, &parsed_license));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true,
|
||||
true, request_hash, nullptr, &clock_values,
|
||||
&nonce_values, &parsed_license));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true,
|
||||
true, nullptr, &timer_limits, &clock_values,
|
||||
&nonce_values, &parsed_license));
|
||||
EXPECT_EQ(
|
||||
ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true, true,
|
||||
&timer_limits, &clock_values, &nonce_values, nullptr));
|
||||
EXPECT_EQ(
|
||||
ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true, true,
|
||||
&timer_limits, &clock_values, nullptr, &parsed_license));
|
||||
EXPECT_EQ(
|
||||
ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true, true,
|
||||
&timer_limits, nullptr, &nonce_values, &parsed_license));
|
||||
EXPECT_EQ(
|
||||
ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true, true,
|
||||
nullptr, &clock_values, &nonce_values, &parsed_license));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(nullptr, message_size, core_message_length, true,
|
||||
true, request_hash, &timer_limits, &clock_values,
|
||||
&nonce_values, &parsed_license));
|
||||
true, &timer_limits, &clock_values, &nonce_values,
|
||||
&parsed_license));
|
||||
|
||||
constexpr uint64_t system_time = 0;
|
||||
uint64_t timer_value = 0;
|
||||
@@ -413,6 +454,21 @@ TEST(OdkTest, PrepareCoreProvisioningRequest) {
|
||||
&core_message_length, &nonce_values, device_id, sizeof(device_id)));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreRenewedProvisioningRequest) {
|
||||
uint8_t provisioning_message[ODK_RENEWED_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(provisioning_message);
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
|
||||
uint8_t renewal_data[ODK_KEYBOX_RENEWAL_DATA_SIZE] = {0};
|
||||
EXPECT_EQ(
|
||||
OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
provisioning_message, sizeof(provisioning_message),
|
||||
&core_message_length, &nonce_values, device_id, sizeof(device_id),
|
||||
OEMCrypto_RenewalACert, renewal_data, sizeof(renewal_data)));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreProvisioningRequestDeviceId) {
|
||||
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(provisioning_message);
|
||||
@@ -426,6 +482,36 @@ TEST(OdkTest, PrepareCoreProvisioningRequestDeviceId) {
|
||||
sizeof(device_id_invalid)));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreRenewedProvisioningRequestDeviceId) {
|
||||
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(provisioning_message);
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
uint8_t device_id_invalid[ODK_DEVICE_ID_LEN_MAX + 1] = {0};
|
||||
uint8_t renewal_data[ODK_KEYBOX_RENEWAL_DATA_SIZE] = {0};
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
provisioning_message, sizeof(provisioning_message),
|
||||
&core_message_length, &nonce_values, device_id_invalid,
|
||||
sizeof(device_id_invalid), OEMCrypto_RenewalACert, renewal_data,
|
||||
sizeof(renewal_data)));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreRenewedProvisioningRequestRenewalDataInvalid) {
|
||||
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(provisioning_message);
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
|
||||
uint8_t renewal_data_invalid[ODK_KEYBOX_RENEWAL_DATA_SIZE + 1] = {0};
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
provisioning_message, sizeof(provisioning_message),
|
||||
&core_message_length, &nonce_values, device_id,
|
||||
sizeof(device_id), OEMCrypto_RenewalACert, renewal_data_invalid,
|
||||
sizeof(renewal_data_invalid)));
|
||||
}
|
||||
|
||||
// Serialize and de-serialize license request
|
||||
TEST(OdkTest, LicenseRequestRoundtrip) {
|
||||
std::vector<ODK_Field> empty;
|
||||
@@ -488,9 +574,42 @@ TEST(OdkTest, ProvisionRequestRoundtrip) {
|
||||
kdo_parse_func);
|
||||
}
|
||||
|
||||
TEST(OdkTest, RenewedProvisionRequestRoundtrip) {
|
||||
uint32_t device_id_length = ODK_DEVICE_ID_LEN_MAX / 2;
|
||||
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
|
||||
memset(device_id, 0xff, device_id_length);
|
||||
uint16_t renewal_type = OEMCrypto_RenewalACert;
|
||||
uint32_t renewal_data_length = ODK_KEYBOX_RENEWAL_DATA_SIZE / 2;
|
||||
uint8_t renewal_data[ODK_KEYBOX_RENEWAL_DATA_SIZE] = {0};
|
||||
memset(renewal_data, 0xff, renewal_data_length);
|
||||
std::vector<ODK_Field> extra_fields = {
|
||||
{ODK_UINT32, &device_id_length, "device_id_length"},
|
||||
{ODK_DEVICEID, device_id, "device_id"},
|
||||
{ODK_UINT16, &renewal_type, "renewal_type"},
|
||||
{ODK_UINT32, &renewal_data_length, "renewal_data_length"},
|
||||
{ODK_RENEWALDATA, renewal_data, "renewal_data"},
|
||||
};
|
||||
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
return ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
buf, SIZE_MAX, size, nonce_values, device_id, device_id_length,
|
||||
renewal_type, renewal_data, renewal_data_length);
|
||||
};
|
||||
auto kdo_parse_func =
|
||||
[&](const std::string& oemcrypto_core_message,
|
||||
ODK_ProvisioningRequest* core_provisioning_request) {
|
||||
bool ok = CoreRenewedProvisioningRequestFromMessage(
|
||||
oemcrypto_core_message, core_provisioning_request);
|
||||
return ok;
|
||||
};
|
||||
ValidateRequest<ODK_ProvisioningRequest>(
|
||||
ODK_Renewed_Provisioning_Request_Type, extra_fields, odk_prepare_func,
|
||||
kdo_parse_func);
|
||||
}
|
||||
|
||||
TEST(OdkTest, ParseLicenseErrorNonce) {
|
||||
ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms);
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION);
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
@@ -499,7 +618,7 @@ TEST(OdkTest, ParseLicenseErrorNonce) {
|
||||
params.core_message.nonce_values.nonce = 0;
|
||||
OEMCryptoResult err = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, params.request_hash, &(params.timer_limits),
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
EXPECT_EQ(OEMCrypto_ERROR_INVALID_NONCE, err);
|
||||
@@ -508,7 +627,7 @@ TEST(OdkTest, ParseLicenseErrorNonce) {
|
||||
|
||||
TEST(OdkTest, ParseLicenseErrorUsageEntry) {
|
||||
ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms);
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION);
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
@@ -516,25 +635,59 @@ TEST(OdkTest, ParseLicenseErrorUsageEntry) {
|
||||
params.usage_entry_present = false;
|
||||
OEMCryptoResult err = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, params.request_hash, &(params.timer_limits),
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
TEST(OdkTest, ParseLicenseErrorRequestHash) {
|
||||
TEST(OdkTest, ParseLicenseNullSubstring) {
|
||||
ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms);
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION);
|
||||
params.parsed_license.srm_restriction_data.offset = 0;
|
||||
params.parsed_license.srm_restriction_data.length = 0;
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
&buf_size);
|
||||
OEMCryptoResult result = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, result);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
TEST(OdkTest, ParseLicenseErrorSubstringOffset) {
|
||||
// offset out of range
|
||||
ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION);
|
||||
params.parsed_license.enc_mac_keys_iv.offset = 1024;
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
&buf_size);
|
||||
// temporarily mess up with request hash
|
||||
params.request_hash[0] = 0xff;
|
||||
OEMCryptoResult err = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, params.request_hash, &(params.timer_limits),
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
|
||||
delete[] buf;
|
||||
|
||||
// offset + length out of range
|
||||
err = OEMCrypto_SUCCESS;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION);
|
||||
params.parsed_license.enc_mac_keys_iv.length = buf_size;
|
||||
buf = nullptr;
|
||||
buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
&buf_size);
|
||||
err = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
|
||||
@@ -582,21 +735,28 @@ class OdkVersionTest : public ::testing::Test,
|
||||
GetParam().response_major_version;
|
||||
params->core_message.nonce_values.api_minor_version =
|
||||
GetParam().response_minor_version;
|
||||
features_ =
|
||||
CoreMessageFeatures::DefaultFeatures(GetParam().maximum_major_version);
|
||||
}
|
||||
CoreMessageFeatures features_;
|
||||
};
|
||||
|
||||
// Serialize and de-serialize license response
|
||||
TEST_P(OdkVersionTest, LicenseResponseRoundtrip) {
|
||||
ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms);
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms,
|
||||
GetParam().response_major_version);
|
||||
SetRequestVersion(¶ms);
|
||||
// save a copy of params.request_hash as it will be zero out during the test
|
||||
// For v17, we do not use the hash to verify the request. However, the server
|
||||
// needs to be backwards compatible, so it still needs to pass the hash into
|
||||
// CreateCoreLiceseseResponse below. Save a copy of params.request_hash as it
|
||||
// will be zero out during the test
|
||||
uint8_t request_hash_read[ODK_SHA256_HASH_SIZE];
|
||||
memcpy(request_hash_read, params.request_hash, sizeof(request_hash_read));
|
||||
auto odk_parse_func = [&](const uint8_t* buf, size_t size) {
|
||||
return ODK_ParseLicense(
|
||||
buf, size + kExtraPayloadSize, size, params.initial_license_load,
|
||||
params.usage_entry_present, request_hash_read, &(params.timer_limits),
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
};
|
||||
@@ -605,8 +765,8 @@ TEST_P(OdkVersionTest, LicenseResponseRoundtrip) {
|
||||
sizeof(request_hash_read));
|
||||
auto kdo_prepare_func = [&](const ODK_LicenseRequest& core_request,
|
||||
std::string* oemcrypto_core_message) {
|
||||
return CreateCoreLicenseResponse(params.parsed_license, core_request,
|
||||
request_hash_string,
|
||||
return CreateCoreLicenseResponse(features_, params.parsed_license,
|
||||
core_request, request_hash_string,
|
||||
oemcrypto_core_message);
|
||||
};
|
||||
ValidateResponse<ODK_LicenseRequest>(GetParam(), &(params.core_message),
|
||||
@@ -636,7 +796,7 @@ TEST_P(OdkVersionTest, RenewalResponseRoundtrip) {
|
||||
auto kdo_prepare_func = [&](ODK_RenewalRequest& core_request,
|
||||
std::string* oemcrypto_core_message) {
|
||||
core_request.playback_time_seconds = playback_clock;
|
||||
return CreateCoreRenewalResponse(core_request, renewal_duration,
|
||||
return CreateCoreRenewalResponse(features_, core_request, renewal_duration,
|
||||
oemcrypto_core_message);
|
||||
};
|
||||
ValidateResponse<ODK_RenewalRequest>(GetParam(), &(params.core_message),
|
||||
@@ -663,7 +823,7 @@ TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) {
|
||||
std::string* oemcrypto_core_message) {
|
||||
core_request.device_id.assign(reinterpret_cast<char*>(device_id),
|
||||
device_id_length);
|
||||
return CreateCoreProvisioningResponse(params.parsed_provisioning,
|
||||
return CreateCoreProvisioningResponse(features_, params.parsed_provisioning,
|
||||
core_request, oemcrypto_core_message);
|
||||
};
|
||||
ValidateResponse<ODK_ProvisioningRequest>(GetParam(), &(params.core_message),
|
||||
@@ -687,26 +847,37 @@ const uint16_t kOldMajorMinor = ODK_MAJOR_VERSION > ODK_FIRST_VERSION ? 42 : 0;
|
||||
// List of major and minor versions to test.
|
||||
std::vector<VersionParameters> TestCases() {
|
||||
std::vector<VersionParameters> test_cases{
|
||||
// Fields: request major, request minor, response major, response minor
|
||||
{ODK_MAJOR_VERSION, ODK_MINOR_VERSION, ODK_MAJOR_VERSION,
|
||||
// Fields: maximum major version,
|
||||
// request major, request minor, response major, response minor,
|
||||
{ODK_MAJOR_VERSION, ODK_MAJOR_VERSION, ODK_MINOR_VERSION,
|
||||
ODK_MAJOR_VERSION, ODK_MINOR_VERSION},
|
||||
{ODK_MAJOR_VERSION, ODK_MAJOR_VERSION, ODK_MINOR_VERSION + 1,
|
||||
ODK_MAJOR_VERSION, ODK_MINOR_VERSION},
|
||||
{ODK_MAJOR_VERSION, ODK_MAJOR_VERSION, kOldMinor, ODK_MAJOR_VERSION,
|
||||
kOldMinor},
|
||||
{ODK_MAJOR_VERSION, ODK_MAJOR_VERSION, 0, ODK_MAJOR_VERSION, 0},
|
||||
{ODK_MAJOR_VERSION, ODK_MAJOR_VERSION + 1, 42, ODK_MAJOR_VERSION,
|
||||
ODK_MINOR_VERSION},
|
||||
{ODK_MAJOR_VERSION, ODK_MINOR_VERSION + 1, ODK_MAJOR_VERSION,
|
||||
ODK_MINOR_VERSION},
|
||||
{ODK_MAJOR_VERSION, kOldMinor, ODK_MAJOR_VERSION, kOldMinor},
|
||||
{ODK_MAJOR_VERSION, 0, ODK_MAJOR_VERSION, 0},
|
||||
{ODK_MAJOR_VERSION + 1, 42, ODK_MAJOR_VERSION, ODK_MINOR_VERSION},
|
||||
{kOldMajor, 0, kOldMajor, 0},
|
||||
{kOldMajor, kOldMajorMinor, kOldMajor, kOldMajorMinor},
|
||||
{ODK_MAJOR_VERSION, kOldMajor, 0, kOldMajor, 0},
|
||||
{ODK_MAJOR_VERSION, kOldMajor, kOldMajorMinor, kOldMajor, kOldMajorMinor},
|
||||
// If the server is restricted to v16, then the response can be at
|
||||
// most 16.5
|
||||
{16, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 16, 5},
|
||||
// Here are some known good versions. Make extra sure they work.
|
||||
{16, 3, 16, 3},
|
||||
{16, 4, 16, 4},
|
||||
{16, 5, 16, 5},
|
||||
{16, 16, 3, 16, 3},
|
||||
{16, 16, 4, 16, 4},
|
||||
{16, 16, 5, 16, 5},
|
||||
{17, 16, 3, 16, 3},
|
||||
{17, 16, 4, 16, 4},
|
||||
{17, 16, 5, 16, 5},
|
||||
{17, 17, 0, 17, 0},
|
||||
{17, 17, 1, 17, 1},
|
||||
};
|
||||
return test_cases;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(OdkVersionTests, OdkVersionTest,
|
||||
::testing::ValuesIn(TestCases()));
|
||||
INSTANTIATE_TEST_SUITE_P(OdkVersionTests, OdkVersionTest,
|
||||
::testing::ValuesIn(TestCases()));
|
||||
|
||||
TEST(OdkSizeTest, LicenseRequest) {
|
||||
uint8_t* message = nullptr;
|
||||
@@ -766,7 +937,7 @@ TEST(OdkSizeTest, ReleaseRequest) {
|
||||
&core_message_length, &nonce_values,
|
||||
&clock_values, system_time_seconds));
|
||||
// Release requests do not have a core message.
|
||||
EXPECT_GE(core_message_length, 0);
|
||||
EXPECT_GE(core_message_length, 0u);
|
||||
}
|
||||
|
||||
TEST(OdkSizeTest, ProvisioningRequest) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
# source code may only be used and distributed under the Widevine Master License
|
||||
# source code may only be used and distributed under the Widevine License
|
||||
# Agreement.
|
||||
|
||||
{
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "odk_test_helper.h"
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "odk_endian.h"
|
||||
#include "odk_structs.h"
|
||||
#include "odk_structs_priv.h"
|
||||
|
||||
@@ -31,7 +31,8 @@ void ODK_SetDefaultCoreFields(ODK_CoreMessage* core_message,
|
||||
core_message->nonce_values.session_id = 0xcafebabe;
|
||||
}
|
||||
|
||||
void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params) {
|
||||
void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params,
|
||||
uint32_t odk_major_version) {
|
||||
ODK_SetDefaultCoreFields(&(params->core_message), ODK_License_Response_Type);
|
||||
params->initial_license_load = true;
|
||||
params->usage_entry_present = true;
|
||||
@@ -51,6 +52,29 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params) {
|
||||
.total_playback_duration_seconds = 12,
|
||||
.initial_renewal_duration_seconds = 13,
|
||||
},
|
||||
.watermarking = 0,
|
||||
.dtcp2_required = {.dtcp2_required = 0,
|
||||
.cmi_descriptor_0 =
|
||||
{
|
||||
.id = 0,
|
||||
.extension = 0,
|
||||
.length = 1,
|
||||
.data = 0,
|
||||
},
|
||||
.cmi_descriptor_1 =
|
||||
{
|
||||
.id = 1,
|
||||
.extension = 0,
|
||||
.length = 3,
|
||||
.data = {0, 0, 0},
|
||||
},
|
||||
.cmi_descriptor_2 =
|
||||
{
|
||||
.id = 2,
|
||||
.extension = 0,
|
||||
.length = 3,
|
||||
.data = {0, 0, 0},
|
||||
}},
|
||||
.key_array_length = 3,
|
||||
.key_array =
|
||||
{
|
||||
@@ -87,10 +111,10 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params) {
|
||||
".srm_restriction_data"},
|
||||
{ODK_UINT32, &(params->parsed_license.license_type), ".license_type"},
|
||||
{ODK_UINT32, &(params->parsed_license.nonce_required), ".nonce_required"},
|
||||
{ODK_UINT32,
|
||||
{ODK_BOOL,
|
||||
&(params->parsed_license.timer_limits.soft_enforce_rental_duration),
|
||||
".soft_enforce_rental_duration"},
|
||||
{ODK_UINT32,
|
||||
{ODK_BOOL,
|
||||
&(params->parsed_license.timer_limits.soft_enforce_playback_duration),
|
||||
".soft_enforce_playback_duration"},
|
||||
{ODK_UINT64,
|
||||
@@ -105,37 +129,132 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params) {
|
||||
{ODK_UINT64,
|
||||
&(params->parsed_license.timer_limits.initial_renewal_duration_seconds),
|
||||
".initial_renewal_duration_seconds"},
|
||||
{ODK_UINT32, &(params->parsed_license.key_array_length),
|
||||
".key_array_length"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_id), ".key_id"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_data_iv),
|
||||
".key_data_iv"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_data),
|
||||
".key_data"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_control_iv),
|
||||
".key_control_iv"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_control),
|
||||
".key_control"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_id), ".key_id"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_data_iv),
|
||||
".key_data_iv"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_data),
|
||||
".key_data"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_control_iv),
|
||||
".key_control_iv"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_control),
|
||||
".key_control"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_id), ".key_id"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_data_iv),
|
||||
".key_data_iv"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_data),
|
||||
".key_data"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_control_iv),
|
||||
".key_control_iv"},
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_control),
|
||||
".key_control"},
|
||||
{ODK_HASH, params->request_hash, ".request_hash"},
|
||||
};
|
||||
if (odk_major_version >= 17) {
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT32, &(params->parsed_license.watermarking), ".watermarking"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8, &(params->parsed_license.dtcp2_required.dtcp2_required),
|
||||
".dtcp2_required"});
|
||||
if (params->parsed_license.dtcp2_required.dtcp2_required) {
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_0.id),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_0.extension),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT16,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_0.length),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_0.data),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_1.id),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_1.extension),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT16,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_1.length),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_1.data[0]),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_1.data[1]),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_1.data[2]),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_2.id),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_2.extension),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT16,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_2.length),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_2.data[0]),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_2.data[1]),
|
||||
".cmi_descriptor_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT8,
|
||||
&(params->parsed_license.dtcp2_required.cmi_descriptor_2.data[2]),
|
||||
".cmi_descriptor_data"});
|
||||
}
|
||||
}
|
||||
params->extra_fields.push_back({ODK_UINT32,
|
||||
&(params->parsed_license.key_array_length),
|
||||
".key_array_length"});
|
||||
params->extra_fields.push_back({ODK_SUBSTRING,
|
||||
&(params->parsed_license.key_array[0].key_id),
|
||||
".key_id"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_data_iv),
|
||||
".key_data_iv"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_data),
|
||||
".key_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_control_iv),
|
||||
".key_control_iv"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[0].key_control),
|
||||
".key_control"});
|
||||
params->extra_fields.push_back({ODK_SUBSTRING,
|
||||
&(params->parsed_license.key_array[1].key_id),
|
||||
".key_id"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_data_iv),
|
||||
".key_data_iv"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_data),
|
||||
".key_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_control_iv),
|
||||
".key_control_iv"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[1].key_control),
|
||||
".key_control"});
|
||||
params->extra_fields.push_back({ODK_SUBSTRING,
|
||||
&(params->parsed_license.key_array[2].key_id),
|
||||
".key_id"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_data_iv),
|
||||
".key_data_iv"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_data),
|
||||
".key_data"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_control_iv),
|
||||
".key_control_iv"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_license.key_array[2].key_control),
|
||||
".key_control"});
|
||||
if (odk_major_version == 16) {
|
||||
params->extra_fields.push_back(
|
||||
{ODK_HASH, params->request_hash, ".request_hash"});
|
||||
}
|
||||
}
|
||||
|
||||
void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params) {
|
||||
@@ -157,7 +276,7 @@ void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params) {
|
||||
.initial_renewal_duration_seconds = 300,
|
||||
};
|
||||
params->clock_values = {
|
||||
.time_of_license_signed =
|
||||
.time_of_license_request_signed =
|
||||
params->system_time - params->playback_clock - 42,
|
||||
.time_of_first_decrypt = params->system_time - params->playback_clock,
|
||||
.time_of_last_decrypt = params->system_time - params->playback_clock,
|
||||
@@ -177,6 +296,7 @@ void ODK_SetDefaultProvisioningResponseParams(
|
||||
memset(params->device_id + params->device_id_length, 0,
|
||||
ODK_DEVICE_ID_LEN_MAX - params->device_id_length);
|
||||
params->parsed_provisioning = {
|
||||
.key_type = OEMCrypto_RSA_Private_Key,
|
||||
.enc_private_key = {.offset = 0, .length = 1},
|
||||
.enc_private_key_iv = {.offset = 2, .length = 3},
|
||||
.encrypted_message_key = {.offset = 4, .length = 5},
|
||||
@@ -196,16 +316,22 @@ void ODK_SetDefaultProvisioningResponseParams(
|
||||
|
||||
size_t ODK_FieldLength(ODK_FieldType type) {
|
||||
switch (type) {
|
||||
case ODK_UINT8:
|
||||
return sizeof(uint8_t);
|
||||
case ODK_UINT16:
|
||||
return sizeof(uint16_t);
|
||||
case ODK_UINT32:
|
||||
return sizeof(uint32_t);
|
||||
case ODK_UINT64:
|
||||
return sizeof(uint64_t);
|
||||
case ODK_BOOL: // Booleans are stored in the message as 32 bit ints.
|
||||
return sizeof(uint32_t);
|
||||
case ODK_SUBSTRING:
|
||||
return sizeof(uint32_t) + sizeof(uint32_t);
|
||||
case ODK_DEVICEID:
|
||||
return ODK_DEVICE_ID_LEN_MAX;
|
||||
case ODK_RENEWALDATA:
|
||||
return ODK_KEYBOX_RENEWAL_DATA_SIZE;
|
||||
case ODK_HASH:
|
||||
return ODK_SHA256_HASH_SIZE;
|
||||
default:
|
||||
@@ -225,30 +351,44 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
switch (field->type) {
|
||||
case ODK_UINT8: {
|
||||
memcpy(buf, field->value, sizeof(uint8_t));
|
||||
break;
|
||||
}
|
||||
case ODK_UINT16: {
|
||||
const uint16_t u16 = htobe16(*static_cast<uint16_t*>(field->value));
|
||||
const uint16_t u16 =
|
||||
oemcrypto_htobe16(*static_cast<uint16_t*>(field->value));
|
||||
memcpy(buf, &u16, sizeof(u16));
|
||||
break;
|
||||
}
|
||||
case ODK_UINT32: {
|
||||
const uint32_t u32 = htobe32(*static_cast<uint32_t*>(field->value));
|
||||
const uint32_t u32 =
|
||||
oemcrypto_htobe32(*static_cast<uint32_t*>(field->value));
|
||||
memcpy(buf, &u32, sizeof(u32));
|
||||
break;
|
||||
}
|
||||
case ODK_UINT64: {
|
||||
const uint64_t u64 = htobe64(*static_cast<uint64_t*>(field->value));
|
||||
const uint64_t u64 =
|
||||
oemcrypto_htobe64(*static_cast<uint64_t*>(field->value));
|
||||
memcpy(buf, &u64, sizeof(u64));
|
||||
break;
|
||||
}
|
||||
case ODK_BOOL: {
|
||||
const bool value = *static_cast<bool*>(field->value);
|
||||
const uint32_t u32 = oemcrypto_htobe32(value ? 1 : 0);
|
||||
memcpy(buf, &u32, sizeof(u32));
|
||||
break;
|
||||
}
|
||||
case ODK_SUBSTRING: {
|
||||
OEMCrypto_Substring* s = static_cast<OEMCrypto_Substring*>(field->value);
|
||||
const uint32_t off = htobe32(s->offset);
|
||||
const uint32_t len = htobe32(s->length);
|
||||
const uint32_t off = oemcrypto_htobe32(s->offset);
|
||||
const uint32_t len = oemcrypto_htobe32(s->length);
|
||||
memcpy(buf, &off, sizeof(off));
|
||||
memcpy(buf + sizeof(off), &len, sizeof(len));
|
||||
break;
|
||||
}
|
||||
case ODK_DEVICEID:
|
||||
case ODK_RENEWALDATA:
|
||||
case ODK_HASH: {
|
||||
const size_t field_len = ODK_FieldLength(field->type);
|
||||
const uint8_t* const id = static_cast<uint8_t*>(field->value);
|
||||
@@ -268,22 +408,33 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf,
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
switch (field->type) {
|
||||
case ODK_UINT8: {
|
||||
memcpy(field->value, buf, sizeof(uint8_t));
|
||||
break;
|
||||
}
|
||||
case ODK_UINT16: {
|
||||
memcpy(field->value, buf, sizeof(uint16_t));
|
||||
uint16_t* u16p = static_cast<uint16_t*>(field->value);
|
||||
*u16p = be16toh(*u16p);
|
||||
*u16p = oemcrypto_be16toh(*u16p);
|
||||
break;
|
||||
}
|
||||
case ODK_UINT32: {
|
||||
memcpy(field->value, buf, sizeof(uint32_t));
|
||||
uint32_t* u32p = static_cast<uint32_t*>(field->value);
|
||||
*u32p = be32toh(*u32p);
|
||||
*u32p = oemcrypto_be32toh(*u32p);
|
||||
break;
|
||||
}
|
||||
case ODK_UINT64: {
|
||||
memcpy(field->value, buf, sizeof(uint64_t));
|
||||
uint64_t* u64p = static_cast<uint64_t*>(field->value);
|
||||
*u64p = be64toh(*u64p);
|
||||
*u64p = oemcrypto_be64toh(*u64p);
|
||||
break;
|
||||
}
|
||||
case ODK_BOOL: {
|
||||
uint32_t value;
|
||||
memcpy(&value, buf, sizeof(uint32_t));
|
||||
value = oemcrypto_be32toh(value);
|
||||
*static_cast<bool*>(field->value) = (value != 0);
|
||||
break;
|
||||
}
|
||||
case ODK_SUBSTRING: {
|
||||
@@ -292,11 +443,12 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf,
|
||||
uint32_t len = 0;
|
||||
memcpy(&off, buf, sizeof(off));
|
||||
memcpy(&len, buf + sizeof(off), sizeof(len));
|
||||
s->offset = be32toh(off);
|
||||
s->length = be32toh(len);
|
||||
s->offset = oemcrypto_be32toh(off);
|
||||
s->length = oemcrypto_be32toh(len);
|
||||
break;
|
||||
}
|
||||
case ODK_DEVICEID:
|
||||
case ODK_RENEWALDATA:
|
||||
case ODK_HASH: {
|
||||
const size_t field_len = ODK_FieldLength(field->type);
|
||||
uint8_t* const id = static_cast<uint8_t*>(field->value);
|
||||
@@ -315,18 +467,26 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf,
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
switch (field->type) {
|
||||
case ODK_UINT16: {
|
||||
uint16_t val;
|
||||
memcpy(&val, buf, sizeof(uint16_t));
|
||||
val = be16toh(val);
|
||||
case ODK_UINT8: {
|
||||
uint8_t val;
|
||||
memcpy(&val, buf, sizeof(uint8_t));
|
||||
std::cerr << field->name << ": " << val << " = 0x" << std::hex << val
|
||||
<< "\n";
|
||||
break;
|
||||
}
|
||||
case ODK_UINT16: {
|
||||
uint16_t val;
|
||||
memcpy(&val, buf, sizeof(uint16_t));
|
||||
val = oemcrypto_be16toh(val);
|
||||
std::cerr << field->name << ": " << val << " = 0x" << std::hex << val
|
||||
<< "\n";
|
||||
break;
|
||||
}
|
||||
case ODK_BOOL:
|
||||
case ODK_UINT32: {
|
||||
uint32_t val;
|
||||
memcpy(&val, buf, sizeof(uint32_t));
|
||||
val = be32toh(val);
|
||||
val = oemcrypto_be32toh(val);
|
||||
std::cerr << field->name << ": " << val << " = 0x" << std::hex << val
|
||||
<< "\n";
|
||||
break;
|
||||
@@ -334,7 +494,7 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf,
|
||||
case ODK_UINT64: {
|
||||
uint64_t val;
|
||||
memcpy(&val, buf, sizeof(uint64_t));
|
||||
val = be64toh(val);
|
||||
val = oemcrypto_be64toh(val);
|
||||
std::cerr << field->name << ": " << val << " = 0x" << std::hex << val
|
||||
<< "\n";
|
||||
break;
|
||||
@@ -348,6 +508,7 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf,
|
||||
break;
|
||||
}
|
||||
case ODK_DEVICEID:
|
||||
case ODK_RENEWALDATA:
|
||||
case ODK_HASH: {
|
||||
const size_t field_len = ODK_FieldLength(field->type);
|
||||
std::cerr << field->name << ": ";
|
||||
@@ -447,7 +608,8 @@ void ODK_ExpectEqualBuf(const void* s1, const void* s2, size_t n,
|
||||
std::fstream out(tmp, std::ios::out | std::ios::binary);
|
||||
out.write(static_cast<const char*>(buffers[i]), n);
|
||||
out.close();
|
||||
std::cerr << "buffer " << i << " dumped to " << tmp << std::endl;
|
||||
std::cerr << std::endl
|
||||
<< "Message buffer " << i << " dumped to " << tmp << std::endl;
|
||||
size_t bytes_written;
|
||||
uint8_t* buf =
|
||||
const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(buffers[i]));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_
|
||||
@@ -15,13 +15,20 @@
|
||||
namespace wvodk_test {
|
||||
|
||||
enum ODK_FieldType {
|
||||
ODK_UINT8,
|
||||
ODK_UINT16,
|
||||
ODK_UINT32,
|
||||
ODK_UINT64,
|
||||
ODK_SUBSTRING,
|
||||
ODK_DEVICEID,
|
||||
ODK_RENEWALDATA,
|
||||
ODK_HASH,
|
||||
ODK_NUMTYPES,
|
||||
// The "stressable" types are the ones we can put in a stress test that packs
|
||||
// and unpacks random data and can expect to get back the same thing.
|
||||
ODK_LAST_STRESSABLE_TYPE,
|
||||
// Put boolean after ODK_LAST_STRESSABLE_TYPE, so that we skip boolean type in
|
||||
// SerializeFieldsStress because we unpack any nonzero to 'true'.
|
||||
ODK_BOOL,
|
||||
};
|
||||
|
||||
enum ODK_FieldMode {
|
||||
@@ -36,6 +43,8 @@ struct ODK_Field {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
// This structure contains all parameters available in message version v16
|
||||
// through the current version.
|
||||
struct ODK_LicenseResponseParams {
|
||||
ODK_CoreMessage core_message;
|
||||
bool initial_license_load;
|
||||
@@ -69,7 +78,8 @@ struct ODK_ProvisioningResponseParams {
|
||||
// Default values in core_message for testing
|
||||
void ODK_SetDefaultCoreFields(ODK_CoreMessage* core_message,
|
||||
ODK_MessageType message_type);
|
||||
void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params);
|
||||
void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params,
|
||||
uint32_t odk_major_version);
|
||||
void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params);
|
||||
void ODK_SetDefaultProvisioningResponseParams(
|
||||
ODK_ProvisioningResponseParams* params);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
@@ -38,7 +38,7 @@ TEST(OdkTimerBasicTest, Init) {
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
uint64_t time = 42;
|
||||
ODK_InitializeClockValues(&clock_values, time);
|
||||
EXPECT_EQ(clock_values.time_of_license_signed, time);
|
||||
EXPECT_EQ(clock_values.time_of_license_request_signed, time);
|
||||
EXPECT_EQ(clock_values.time_of_first_decrypt, 0u);
|
||||
EXPECT_EQ(clock_values.time_of_last_decrypt, 0u);
|
||||
EXPECT_EQ(clock_values.time_when_timer_expires, 0u);
|
||||
@@ -59,7 +59,7 @@ TEST(OdkTimerBasicTest, Reload) {
|
||||
enum OEMCrypto_Usage_Entry_Status status = kInactiveUsed;
|
||||
ODK_ReloadClockValues(&clock_values, lic_signed, first_decrypt, last_decrypt,
|
||||
status, time);
|
||||
EXPECT_EQ(clock_values.time_of_license_signed, lic_signed);
|
||||
EXPECT_EQ(clock_values.time_of_license_request_signed, lic_signed);
|
||||
EXPECT_EQ(clock_values.time_of_first_decrypt, first_decrypt);
|
||||
EXPECT_EQ(clock_values.time_of_last_decrypt, last_decrypt);
|
||||
EXPECT_EQ(clock_values.time_when_timer_expires, 0u);
|
||||
@@ -95,7 +95,7 @@ class ODKTimerTest : public ::testing::Test {
|
||||
// Start rental clock at kRentalClockStart. This happens when the license
|
||||
// request is signed.
|
||||
ODK_InitializeClockValues(&clock_values_, kRentalClockStart);
|
||||
EXPECT_EQ(clock_values_.time_of_license_signed, kRentalClockStart);
|
||||
EXPECT_EQ(clock_values_.time_of_license_request_signed, kRentalClockStart);
|
||||
}
|
||||
|
||||
// Simulate loading or reloading a license in a new session. An offline
|
||||
@@ -113,14 +113,14 @@ class ODKTimerTest : public ::testing::Test {
|
||||
ODK_InitializeClockValues(&clock_values_, 0);
|
||||
// When the usage entry is reloaded, the clock values are reloaded.
|
||||
ODK_ReloadClockValues(&clock_values_,
|
||||
old_clock_values.time_of_license_signed,
|
||||
old_clock_values.time_of_license_request_signed,
|
||||
old_clock_values.time_of_first_decrypt,
|
||||
old_clock_values.time_of_last_decrypt,
|
||||
old_clock_values.status, system_time);
|
||||
EXPECT_EQ(clock_values_.timer_status,
|
||||
ODK_CLOCK_TIMER_STATUS_LICENSE_NOT_LOADED);
|
||||
// These shall not change:
|
||||
EXPECT_EQ(clock_values_.time_of_license_signed, kRentalClockStart);
|
||||
EXPECT_EQ(clock_values_.time_of_license_request_signed, kRentalClockStart);
|
||||
EXPECT_EQ(clock_values_.time_of_first_decrypt,
|
||||
old_clock_values.time_of_first_decrypt);
|
||||
EXPECT_EQ(clock_values_.time_of_last_decrypt,
|
||||
@@ -215,8 +215,8 @@ class ODKTimerTest : public ::testing::Test {
|
||||
ODK_TIMER_EXPIRED);
|
||||
// These should not have changed. In particular, if the license was unused
|
||||
// before, it should reamin unused.
|
||||
EXPECT_EQ(clock_values_.time_of_license_signed,
|
||||
old_clock_values.time_of_license_signed);
|
||||
EXPECT_EQ(clock_values_.time_of_license_request_signed,
|
||||
old_clock_values.time_of_license_request_signed);
|
||||
EXPECT_EQ(clock_values_.time_of_first_decrypt,
|
||||
old_clock_values.time_of_first_decrypt);
|
||||
EXPECT_EQ(clock_values_.time_of_last_decrypt,
|
||||
@@ -226,7 +226,7 @@ class ODKTimerTest : public ::testing::Test {
|
||||
|
||||
// Verify that the clock values are correct.
|
||||
void CheckClockValues(uint64_t time_of_last_decrypt) {
|
||||
EXPECT_EQ(clock_values_.time_of_license_signed, kRentalClockStart);
|
||||
EXPECT_EQ(clock_values_.time_of_license_request_signed, kRentalClockStart);
|
||||
EXPECT_EQ(clock_values_.time_of_first_decrypt, start_of_playback_);
|
||||
EXPECT_EQ(clock_values_.time_of_last_decrypt, time_of_last_decrypt);
|
||||
EXPECT_EQ(clock_values_.status, kActive);
|
||||
@@ -1133,8 +1133,8 @@ TEST_P(ODKUseCase_LicenseWithRenewal, NullPointerTest) {
|
||||
timer_value_pointer);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(RestrictRenewal, ODKUseCase_LicenseWithRenewal,
|
||||
::testing::Values(0, 1));
|
||||
INSTANTIATE_TEST_SUITE_P(RestrictRenewal, ODKUseCase_LicenseWithRenewal,
|
||||
::testing::Values(0, 1));
|
||||
|
||||
// Limited Duration License. (See above for notes on Use Case tests). The user
|
||||
// has 15 minutes to begin watching the movie. If a renewal is not received,
|
||||
|
||||
Reference in New Issue
Block a user