Update to ODK v18.3
This commit is contained in:
@@ -11,6 +11,7 @@ package {
|
||||
// all of the 'license_kinds' from "vendor_widevine_license"
|
||||
// to get the below license kinds:
|
||||
// legacy_by_exception_only (by exception only)
|
||||
// legacy_proprietary (by exception only)
|
||||
default_applicable_licenses: ["vendor_widevine_license"],
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package {
|
||||
// all of the 'license_kinds' from "vendor_widevine_license"
|
||||
// to get the below license kinds:
|
||||
// legacy_by_exception_only (by exception only)
|
||||
// legacy_proprietary (by exception only)
|
||||
default_applicable_licenses: ["vendor_widevine_license"],
|
||||
}
|
||||
|
||||
|
||||
@@ -113,15 +113,14 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
|
||||
|
||||
OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
size_t device_id_length) {
|
||||
const ODK_NonceValues* nonce_values,
|
||||
const ODK_MessageCounterInfo* counter_info) {
|
||||
OEMCryptoResult (*original_function)(uint8_t*, size_t, size_t*,
|
||||
const ODK_NonceValues*, const uint8_t*,
|
||||
size_t);
|
||||
const ODK_NonceValues*,
|
||||
const ODK_MessageCounterInfo*);
|
||||
original_function = dlsym(RTLD_NEXT, "ODK_PrepareCoreProvisioningRequest");
|
||||
OEMCryptoResult oem_crypto_result =
|
||||
(*original_function)(message, message_length, core_message_length,
|
||||
nonce_values, device_id, device_id_length);
|
||||
OEMCryptoResult oem_crypto_result = (*original_function)(
|
||||
message, message_length, core_message_length, nonce_values, counter_info);
|
||||
char* file_name = GetFileName("provisioning_request_corpus");
|
||||
|
||||
// Provisioning Request format expected by fuzzer - [Core Provisioning
|
||||
@@ -134,18 +133,19 @@ OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
|
||||
OEMCryptoResult ODK_ParseProvisioning(
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
size_t device_id_length, ODK_ParsedProvisioning* parsed_response) {
|
||||
size_t device_id_length, ODK_MessageCounterInfo* counter_info,
|
||||
ODK_ParsedProvisioning* parsed_response) {
|
||||
struct ODK_ParseProvisioning_Args parse_provisioning_args;
|
||||
parse_provisioning_args.nonce_values = *nonce_values;
|
||||
memcpy(parse_provisioning_args.device_id, device_id, device_id_length);
|
||||
parse_provisioning_args.device_id_length = device_id_length;
|
||||
OEMCryptoResult (*original_function)(const uint8_t*, size_t, size_t,
|
||||
const ODK_NonceValues*, const uint8_t*,
|
||||
size_t, ODK_ParsedProvisioning*);
|
||||
OEMCryptoResult (*original_function)(
|
||||
const uint8_t*, size_t, size_t, const ODK_NonceValues*, const uint8_t*,
|
||||
size_t, ODK_MessageCounterInfo*, ODK_ParsedProvisioning*);
|
||||
original_function = dlsym(RTLD_NEXT, "ODK_ParseProvisioning");
|
||||
OEMCryptoResult oem_crypto_result = (*original_function)(
|
||||
message, message_length, core_message_length, nonce_values, device_id,
|
||||
device_id_length, parsed_response);
|
||||
device_id_length, counter_info, parsed_response);
|
||||
char* file_name = GetFileName("provisioning_response_corpus");
|
||||
|
||||
// Provisioning Response format expected by fuzzer -
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
'-Wno-error=cast-qual',
|
||||
],
|
||||
'cflags_cc': [
|
||||
'-std=c++11',
|
||||
'-std=c++14',
|
||||
'-g3',
|
||||
'-O0',
|
||||
'-fsanitize=fuzzer,address,undefined',
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "core_message_types.h"
|
||||
#include "odk.h"
|
||||
#include "odk_attributes.h"
|
||||
#include "odk_structs.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
using features::CoreMessageFeatures;
|
||||
@@ -39,7 +43,11 @@ OEMCryptoResult odk_serialize_LicenseRequest(
|
||||
const void* in UNUSED, uint8_t* out, size_t* size,
|
||||
const ODK_LicenseRequest& core_license_request UNUSED,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values);
|
||||
// TODO(mattfedd): hook up counters to fuzzer
|
||||
const ODK_MessageCounterInfo counter_info = {0, 0, 0, 0, 0,
|
||||
0, 0, {0}, {0}, {0}};
|
||||
return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values,
|
||||
&counter_info);
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_serialize_RenewalRequest(
|
||||
@@ -54,12 +62,13 @@ OEMCryptoResult odk_serialize_RenewalRequest(
|
||||
|
||||
OEMCryptoResult odk_serialize_ProvisioningRequest(
|
||||
const void* in UNUSED, uint8_t* out, size_t* size,
|
||||
const ODK_ProvisioningRequest& core_provisioning,
|
||||
const ODK_ProvisioningRequest& core_provisioning UNUSED,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
const std::string& device_id = core_provisioning.device_id;
|
||||
return ODK_PrepareCoreProvisioningRequest(
|
||||
out, SIZE_MAX, size, nonce_values,
|
||||
reinterpret_cast<const uint8_t*>(device_id.data()), device_id.size());
|
||||
// TODO(mattfedd): hook up counters to fuzzer
|
||||
const ODK_MessageCounterInfo counter_info = {0, 0, 0, 0, 0,
|
||||
0, 0, {0}, {0}, {0}};
|
||||
return ODK_PrepareCoreProvisioningRequest(out, SIZE_MAX, size, nonce_values,
|
||||
&counter_info);
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message,
|
||||
@@ -69,9 +78,9 @@ OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message,
|
||||
ODK_ParsedLicense* parsed_lic) {
|
||||
return ODK_ParseLicense(message, SIZE_MAX, core_message_length,
|
||||
static_cast<bool>(a->initial_license_load),
|
||||
static_cast<bool>(a->usage_entry_present),
|
||||
static_cast<bool>(a->usage_entry_present), 0,
|
||||
&a->timer_limits, &a->clock_values, nonce_values,
|
||||
parsed_lic);
|
||||
parsed_lic, nullptr);
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_deserialize_RenewalResponse(
|
||||
@@ -119,13 +128,32 @@ bool kdo_serialize_LicenseResponse(const ODK_ParseLicense_Args* args,
|
||||
const ODK_ParsedLicense& parsed_lic,
|
||||
std::string* oemcrypto_core_message) {
|
||||
const auto& nonce_values = args->nonce_values;
|
||||
ODK_LicenseRequest core_request{nonce_values.api_minor_version,
|
||||
nonce_values.api_major_version,
|
||||
nonce_values.nonce, nonce_values.session_id};
|
||||
const ODK_MessageCounter counter_info = {0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}};
|
||||
ODK_LicenseRequest core_request{
|
||||
nonce_values.api_minor_version, nonce_values.api_major_version,
|
||||
nonce_values.nonce, nonce_values.session_id, counter_info};
|
||||
std::string core_request_sha_256(
|
||||
reinterpret_cast<const char*>(args->request_hash), ODK_SHA256_HASH_SIZE);
|
||||
ODK_Packing_ParsedLicense parsed_license;
|
||||
parsed_license.enc_mac_keys_iv = parsed_lic.enc_mac_keys_iv;
|
||||
parsed_license.enc_mac_keys = parsed_lic.enc_mac_keys;
|
||||
parsed_license.pst = parsed_lic.pst;
|
||||
parsed_license.srm_restriction_data = parsed_lic.srm_restriction_data;
|
||||
parsed_license.license_type = parsed_lic.license_type;
|
||||
parsed_license.nonce_required = parsed_lic.nonce_required;
|
||||
parsed_license.timer_limits = parsed_lic.timer_limits;
|
||||
parsed_license.watermarking = parsed_lic.watermarking;
|
||||
parsed_license.dtcp2_required = parsed_lic.dtcp2_required;
|
||||
parsed_license.renewal_delay_base = parsed_lic.renewal_delay_base;
|
||||
parsed_license.key_array_length = parsed_lic.key_array_length;
|
||||
std::vector<OEMCrypto_KeyObject> key_array;
|
||||
size_t i;
|
||||
for (i = 0; i < parsed_lic.key_array_length; i++) {
|
||||
key_array.push_back(parsed_lic.key_array[i]);
|
||||
}
|
||||
parsed_license.key_array = key_array.data();
|
||||
return serialize::CreateCoreLicenseResponse(
|
||||
CoreMessageFeatures::kDefaultFeatures, parsed_lic, core_request,
|
||||
CoreMessageFeatures::kDefaultFeatures, parsed_license, core_request,
|
||||
core_request_sha_256, oemcrypto_core_message);
|
||||
}
|
||||
|
||||
@@ -151,11 +179,17 @@ bool kdo_serialize_ProvisioningResponse(
|
||||
if (args->device_id_length > sizeof(args->device_id)) {
|
||||
return false;
|
||||
}
|
||||
const ODK_MessageCounter counter_info = {0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}};
|
||||
ODK_ProvisioningRequest core_request{
|
||||
nonce_values.api_minor_version, nonce_values.api_major_version,
|
||||
nonce_values.nonce, nonce_values.session_id,
|
||||
nonce_values.api_minor_version,
|
||||
nonce_values.api_major_version,
|
||||
nonce_values.nonce,
|
||||
nonce_values.session_id,
|
||||
std::string(reinterpret_cast<const char*>(args->device_id),
|
||||
args->device_id_length)};
|
||||
args->device_id_length),
|
||||
0,
|
||||
"",
|
||||
counter_info};
|
||||
return serialize::CreateCoreProvisioningResponse(
|
||||
CoreMessageFeatures::kDefaultFeatures, parsed_prov, core_request,
|
||||
oemcrypto_core_message);
|
||||
|
||||
@@ -2,14 +2,30 @@
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "core_message_deserialize.h"
|
||||
#include "core_message_features.h"
|
||||
#include "core_message_serialize_proto.h"
|
||||
#include "core_message_types.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "odk.h"
|
||||
#include "third_party/absl/strings/escaping.h"
|
||||
|
||||
namespace wvodk_test {
|
||||
|
||||
using oemcrypto_core_message::ODK_CommonRequest;
|
||||
using oemcrypto_core_message::ODK_ProvisioningRequest;
|
||||
using oemcrypto_core_message::deserialize::CoreCommonRequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage;
|
||||
using oemcrypto_core_message::features::CoreMessageFeatures;
|
||||
using oemcrypto_core_message::serialize::
|
||||
CreateCoreProvisioningResponseFromProto;
|
||||
|
||||
TEST(CoreMessageTest, RenwalRequest) {
|
||||
std::string oem =
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst"
|
||||
@@ -36,4 +52,145 @@ TEST(CoreMessageTest, RenwalRequest) {
|
||||
char* m = reinterpret_cast<char*>(message);
|
||||
VLOG(0) << absl::BytesToHexString(std::string(m, core_message_length));
|
||||
}
|
||||
|
||||
TEST(CoreMessageTest, ParseCoreCommonRequestFromMessage) {
|
||||
// Core message header format:
|
||||
// message_type : 4 bytes
|
||||
// message_length : 4 bytes
|
||||
// minor_version : 2 bytes
|
||||
// major_version : 2 bytes
|
||||
// nonce : 4 bytes
|
||||
// session_id : 4 bytes
|
||||
const char kv16CoreMessageLicenseRequest[] =
|
||||
"0000000100000014000300100000000100000001";
|
||||
std::string oemcrypto_core_message =
|
||||
absl::HexStringToBytes(kv16CoreMessageLicenseRequest);
|
||||
ODK_CommonRequest odk_common_request;
|
||||
ASSERT_TRUE(CoreCommonRequestFromMessage(oemcrypto_core_message,
|
||||
&odk_common_request));
|
||||
EXPECT_EQ(odk_common_request.message_type, 1);
|
||||
EXPECT_EQ(odk_common_request.message_length, 20);
|
||||
EXPECT_EQ(odk_common_request.api_minor_version, 3);
|
||||
EXPECT_EQ(odk_common_request.api_major_version, 16);
|
||||
EXPECT_EQ(odk_common_request.nonce, 1);
|
||||
EXPECT_EQ(odk_common_request.session_id, 1);
|
||||
}
|
||||
|
||||
struct TestParameters_18V0 {
|
||||
std::string message;
|
||||
uint16_t expected_api_minor_version;
|
||||
uint16_t expected_api_major_version;
|
||||
uint32_t expected_nonce;
|
||||
uint32_t expected_session_id;
|
||||
uint64_t expected_master_generation_number;
|
||||
};
|
||||
|
||||
void PrintTo(const TestParameters_18V0& p, std::ostream* os) {
|
||||
*os << "request = " << p.message << ", expected : {version = v"
|
||||
<< p.expected_api_major_version << "." << p.expected_api_minor_version
|
||||
<< ", nonce = " << p.expected_nonce
|
||||
<< ", session_id = " << p.expected_session_id
|
||||
<< ", master_generation_number = " << p.expected_master_generation_number
|
||||
<< "}";
|
||||
}
|
||||
|
||||
class ProvisioningRoundTripTest_18V0
|
||||
: public ::testing::Test,
|
||||
public ::testing::WithParamInterface<TestParameters_18V0> {};
|
||||
|
||||
// Make sure that the first version of the V18 provisioning request (no hidden
|
||||
// 4-byte value, all 0s in message counter struct) will still parse with
|
||||
// current v18 code. This test is in this file rather than odk_test.cpp
|
||||
// because of the use of absl::HexStringToBytes
|
||||
TEST_P(ProvisioningRoundTripTest_18V0, ProvisioningRoundtrip) {
|
||||
TestParameters_18V0 tc = GetParam();
|
||||
|
||||
ODK_ProvisioningRequest request;
|
||||
|
||||
// Make sure we can parse the request
|
||||
ASSERT_TRUE(CoreProvisioningRequestFromMessage(
|
||||
absl::HexStringToBytes(tc.message), &request));
|
||||
EXPECT_EQ(request.api_minor_version, tc.expected_api_minor_version);
|
||||
EXPECT_EQ(request.api_major_version, tc.expected_api_major_version);
|
||||
EXPECT_EQ(request.nonce, tc.expected_nonce);
|
||||
EXPECT_EQ(request.session_id, tc.expected_session_id);
|
||||
|
||||
if (request.api_major_version >= 18) {
|
||||
EXPECT_EQ(request.counter_info.master_generation_number,
|
||||
tc.expected_master_generation_number);
|
||||
}
|
||||
|
||||
// Make sure we can create a response from that request with the same core
|
||||
// message
|
||||
const CoreMessageFeatures features =
|
||||
CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION);
|
||||
std::string serialized_provisioning_resp;
|
||||
video_widevine::ProvisioningResponse provisioning_response;
|
||||
provisioning_response.set_device_certificate("device_certificate");
|
||||
provisioning_response.set_device_rsa_key("device_rsa_key");
|
||||
provisioning_response.set_device_rsa_key_iv("device_rsa_key_iv");
|
||||
if (!provisioning_response.SerializeToString(&serialized_provisioning_resp)) {
|
||||
FAIL() << "Cannot set up prov response";
|
||||
}
|
||||
std::string oemcrypto_core_message;
|
||||
EXPECT_TRUE(CreateCoreProvisioningResponseFromProto(
|
||||
features, serialized_provisioning_resp, request,
|
||||
OEMCrypto_RSA_Private_Key, &oemcrypto_core_message));
|
||||
|
||||
// Extract core message from generated prov response and match values with
|
||||
// request
|
||||
ODK_CommonRequest odk_common_request;
|
||||
ASSERT_TRUE(CoreCommonRequestFromMessage(oemcrypto_core_message,
|
||||
&odk_common_request));
|
||||
EXPECT_EQ(odk_common_request.message_type, 6u);
|
||||
EXPECT_EQ(odk_common_request.nonce, tc.expected_nonce);
|
||||
EXPECT_EQ(odk_common_request.session_id, tc.expected_session_id);
|
||||
}
|
||||
|
||||
std::vector<TestParameters_18V0> TestCases() {
|
||||
return std::vector<TestParameters_18V0>{
|
||||
// Source: ODKTest ProvisionRequestRoundtrip running on v18.0 ODK checkout
|
||||
{"000000050000005a00000012deadbeefcafebabe12345678abcdffff0000000c0000003"
|
||||
"200000154001200000004ffffffffffffffffffffffffffffffffdddddddddddddddddd"
|
||||
"ddddddddddddddeeeeeeeeeeeeeeeeeeeeeeee",
|
||||
0, 18, 0xdeadbeef, 0xcafebabe, 0x12345678abcdffff},
|
||||
// same as previous request, but replace counter info with all 0s
|
||||
{"000000050000005a00000012deadbeefcafebabe0000000000000000000000000000000"
|
||||
"00000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"00000000000000000000000000000000000000",
|
||||
0, 18, 0xdeadbeef, 0xcafebabe, 0x0},
|
||||
// Source: ODKTest ProvisionRequestRoundtrip running on v17.2 ODK checkout
|
||||
{"000000050000005800020011deadbeefcafebabe00000020fffffffffffffffffffffff"
|
||||
"fffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000",
|
||||
2, 17, 0xdeadbeef, 0xcafebabe, 0x0},
|
||||
// Source: ODKTest ProvisionRequestRoundtrip running on v18.2 ODK checkout
|
||||
{"000000050000005e00020012deadbeefcafebabe0000004012345678abcdffff0000000"
|
||||
"c0000003200000154001200020004ffffffffffffffffffffffffffffffffdddddddddd"
|
||||
"ddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeee",
|
||||
2, 18, 0xdeadbeef, 0xcafebabe, 0x12345678abcdffff},
|
||||
// Source: CDM unit tests on oemcrypto-v18 internal commit 5c77383 (pre
|
||||
// v18.0 -> v18.1 ODK bump)
|
||||
{"000000050000005a00000012b85dfa09000000000000000000000000000000000000000"
|
||||
"00000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"00000000000000000000000000000000000000",
|
||||
0, 18, 0xb85dfa09, 0x0, 0x0},
|
||||
// Same as above but non-zero counter info
|
||||
{"000000050000005a00000012b85dfa09000000001000000000000001000000000000000"
|
||||
"00000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"00000000000000000000000000000000000000",
|
||||
0, 18, 0xb85dfa09, 0x0, 0x1000000000000001},
|
||||
// Source: CDM unit tests on oemcrypto-v18 internal commit fc46827a (post
|
||||
// v18.0 -> v18.1 ODK bump)
|
||||
{"000000050000005e000100127c8ac703000000000000004000000000000000000000000"
|
||||
"00000000000000000001200010000746573740000000000000000000000007465737400"
|
||||
"0000000000000000000000000000000000000000000000",
|
||||
1, 18, 0x7c8ac703, 0x0, 0x0},
|
||||
};
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ProvisioningRoundTripTests_18V0,
|
||||
ProvisioningRoundTripTest_18V0,
|
||||
::testing::ValuesIn(TestCases()));
|
||||
|
||||
} // namespace wvodk_test
|
||||
|
||||
4132
oemcrypto/odk/test/odk_golden_v16.cpp
Normal file
4132
oemcrypto/odk/test/odk_golden_v16.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3846
oemcrypto/odk/test/odk_golden_v17.cpp
Normal file
3846
oemcrypto/odk/test/odk_golden_v17.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4574
oemcrypto/odk/test/odk_golden_v18.cpp
Normal file
4574
oemcrypto/odk/test/odk_golden_v18.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,16 +4,22 @@
|
||||
|
||||
#include "odk.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "core_message_deserialize.h"
|
||||
#include "core_message_features.h"
|
||||
#include "core_message_serialize.h"
|
||||
#include "core_message_serialize_proto.h"
|
||||
#include "core_message_types.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "odk_overflow.h"
|
||||
#include "odk_structs.h"
|
||||
#include "odk_structs_priv.h"
|
||||
#include "odk_test_helper.h"
|
||||
|
||||
@@ -21,11 +27,16 @@ namespace wvodk_test {
|
||||
|
||||
namespace {
|
||||
|
||||
using oemcrypto_core_message::ODK_CommonRequest;
|
||||
using oemcrypto_core_message::ODK_LicenseRequest;
|
||||
using oemcrypto_core_message::ODK_MessageCounter;
|
||||
using oemcrypto_core_message::ODK_Provisioning40Request;
|
||||
using oemcrypto_core_message::ODK_ProvisioningRequest;
|
||||
using oemcrypto_core_message::ODK_RenewalRequest;
|
||||
|
||||
using oemcrypto_core_message::deserialize::CoreCommonRequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::CoreLicenseRequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::CoreProvisioning40RequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::CoreRenewalRequestFromMessage;
|
||||
using oemcrypto_core_message::deserialize::
|
||||
@@ -34,7 +45,10 @@ using oemcrypto_core_message::deserialize::
|
||||
using oemcrypto_core_message::features::CoreMessageFeatures;
|
||||
|
||||
using oemcrypto_core_message::serialize::CreateCoreLicenseResponse;
|
||||
using oemcrypto_core_message::serialize::CreateCoreProvisioning40Response;
|
||||
using oemcrypto_core_message::serialize::CreateCoreProvisioningResponse;
|
||||
using oemcrypto_core_message::serialize::
|
||||
CreateCoreProvisioningResponseFromProto;
|
||||
using oemcrypto_core_message::serialize::CreateCoreRenewalResponse;
|
||||
|
||||
constexpr uint32_t kExtraPayloadSize = 128u;
|
||||
@@ -59,6 +73,40 @@ void PrintTo(const VersionParameters& p, std::ostream* os) {
|
||||
<< p.response_minor_version;
|
||||
}
|
||||
|
||||
void SetDefaultSerializedProvisioningResponse(std::string* serialized_message) {
|
||||
// Create a dummy provisioning response
|
||||
video_widevine::ProvisioningResponse provisioning_response;
|
||||
provisioning_response.set_device_certificate("device_certificate");
|
||||
provisioning_response.set_device_rsa_key("device_rsa_key");
|
||||
provisioning_response.set_device_rsa_key_iv("device_rsa_key_iv");
|
||||
if (!provisioning_response.SerializeToString(serialized_message)) {
|
||||
FAIL();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckCounterInfoIsEqual(ODK_MessageCounterInfo* a, ODK_MessageCounter* b) {
|
||||
if (!a || !b) return false;
|
||||
|
||||
EXPECT_EQ(a->master_generation_number, b->master_generation_number);
|
||||
EXPECT_EQ(a->provisioning_count, b->provisioning_count);
|
||||
EXPECT_EQ(a->license_count, b->license_count);
|
||||
EXPECT_EQ(a->decrypt_count, b->decrypt_count);
|
||||
EXPECT_EQ(a->major_version, b->major_version);
|
||||
EXPECT_EQ(a->minor_version, b->minor_version);
|
||||
EXPECT_EQ(a->patch_version, b->patch_version);
|
||||
for (size_t i = 0; i < sizeof(a->soc_vendor); i++) {
|
||||
EXPECT_EQ(a->soc_vendor[i], b->soc_vendor[i]);
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(a->chipset_model); i++) {
|
||||
EXPECT_EQ(a->chipset_model[i], b->chipset_model[i]);
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(a->extra); i++) {
|
||||
EXPECT_EQ(a->extra[i], b->extra[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename G>
|
||||
void ValidateRequest(uint32_t message_type,
|
||||
const std::vector<ODK_Field>& extra_fields,
|
||||
@@ -241,13 +289,19 @@ TEST(OdkTest, NullRequestTest) {
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
ODK_ClockValues clock_values;
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
memset(&counter_info, 0, sizeof(counter_info));
|
||||
|
||||
// Assert that nullptr does not cause a core dump.
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreLicenseRequest(
|
||||
nullptr, 0uL, nullptr, &nonce_values));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreLicenseRequest(nullptr, 0uL, nullptr, &nonce_values,
|
||||
&counter_info));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreLicenseRequest(nullptr, 0uL, &core_message_length,
|
||||
nullptr));
|
||||
nullptr, &counter_info));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreLicenseRequest(nullptr, 0uL, &core_message_length,
|
||||
&nonce_values, nullptr));
|
||||
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreRenewalRequest(nullptr, 0uL, nullptr, &nonce_values,
|
||||
@@ -261,18 +315,49 @@ TEST(OdkTest, NullRequestTest) {
|
||||
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
nullptr, 0uL, &core_message_length, nullptr, nullptr, 0uL));
|
||||
nullptr, 0uL, &core_message_length, nullptr, &counter_info));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreProvisioningRequest(nullptr, 0uL, nullptr,
|
||||
&nonce_values, nullptr, 0uL));
|
||||
&nonce_values, &counter_info));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
nullptr, 0uL, &core_message_length, &nonce_values, nullptr));
|
||||
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request(
|
||||
nullptr, 0uL, &core_message_length,
|
||||
nullptr, nullptr, 0uL, &counter_info));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request(
|
||||
nullptr, 0uL, nullptr, &nonce_values,
|
||||
nullptr, 0uL, &counter_info));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request(
|
||||
nullptr, 0uL, &core_message_length,
|
||||
&nonce_values, nullptr, 0uL, nullptr));
|
||||
|
||||
// Null device id in provisioning request is ok
|
||||
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
core_message_length = ODK_PROVISIONING_REQUEST_SIZE;
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length,
|
||||
&nonce_values, nullptr, 0uL));
|
||||
if (nonce_values.api_major_version > 17) {
|
||||
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
core_message_length = ODK_PROVISIONING_REQUEST_SIZE;
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length,
|
||||
&nonce_values, &counter_info));
|
||||
} else {
|
||||
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE_V17] = {0};
|
||||
core_message_length = ODK_PROVISIONING_REQUEST_SIZE_V17;
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
message, ODK_PROVISIONING_REQUEST_SIZE_V17,
|
||||
&core_message_length, &nonce_values, &counter_info));
|
||||
}
|
||||
|
||||
// Null device info in provisioning 4.0 request is ok
|
||||
uint8_t message_prov4[ODK_PROVISIONING40_REQUEST_SIZE] = {0};
|
||||
core_message_length = ODK_PROVISIONING40_REQUEST_SIZE;
|
||||
EXPECT_EQ(
|
||||
OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreProvisioning40Request(
|
||||
message_prov4, ODK_PROVISIONING40_REQUEST_SIZE, &core_message_length,
|
||||
&nonce_values, nullptr, 0uL, &counter_info));
|
||||
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
@@ -316,26 +401,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,
|
||||
&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(message, message_size, core_message_length, true,
|
||||
true, 0, &timer_limits, &clock_values,
|
||||
&nonce_values, nullptr, nullptr));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true,
|
||||
true, 0, &timer_limits, &clock_values, nullptr,
|
||||
&parsed_license, nullptr));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true,
|
||||
true, 0, &timer_limits, nullptr, &nonce_values,
|
||||
&parsed_license, nullptr));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(message, message_size, core_message_length, true,
|
||||
true, 0, nullptr, &clock_values, &nonce_values,
|
||||
&parsed_license, nullptr));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseLicense(nullptr, message_size, core_message_length, true,
|
||||
true, &timer_limits, &clock_values, &nonce_values,
|
||||
&parsed_license));
|
||||
true, 0, &timer_limits, &clock_values,
|
||||
&nonce_values, &parsed_license, nullptr));
|
||||
|
||||
constexpr uint64_t system_time = 0;
|
||||
uint64_t timer_value = 0;
|
||||
@@ -373,6 +458,13 @@ TEST(OdkTest, NullResponseTest) {
|
||||
ODK_ParseProvisioning(nullptr, message_size, core_message_length,
|
||||
&nonce_values, device_id,
|
||||
ODK_DEVICE_ID_LEN_MAX, &parsed_response));
|
||||
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseProvisioning40(message, message_size, core_message_length,
|
||||
nullptr));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_ParseProvisioning40(nullptr, message_size, core_message_length,
|
||||
&nonce_values));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreLicenseRequest) {
|
||||
@@ -380,9 +472,12 @@ TEST(OdkTest, PrepareCoreLicenseRequest) {
|
||||
size_t core_message_length = sizeof(license_message);
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, ODK_PrepareCoreLicenseRequest(
|
||||
license_message, sizeof(license_message),
|
||||
&core_message_length, &nonce_values));
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
memset(&counter_info, 0, sizeof(counter_info));
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreLicenseRequest(
|
||||
license_message, sizeof(license_message), &core_message_length,
|
||||
&nonce_values, &counter_info));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreLicenseRequestSize) {
|
||||
@@ -390,18 +485,20 @@ TEST(OdkTest, PrepareCoreLicenseRequestSize) {
|
||||
size_t core_message_length = sizeof(license_message);
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
memset(&counter_info, 0, sizeof(counter_info));
|
||||
// message length smaller than core message length
|
||||
size_t core_message_length_invalid = core_message_length + 1;
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreLicenseRequest(
|
||||
license_message, sizeof(license_message),
|
||||
&core_message_length_invalid, &nonce_values));
|
||||
&core_message_length_invalid, &nonce_values, &counter_info));
|
||||
// message length larger than core message length
|
||||
uint8_t license_message_large[ODK_LICENSE_REQUEST_SIZE * 2] = {0};
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreLicenseRequest(license_message_large,
|
||||
sizeof(license_message_large),
|
||||
&core_message_length, &nonce_values));
|
||||
ODK_PrepareCoreLicenseRequest(
|
||||
license_message_large, sizeof(license_message_large),
|
||||
&core_message_length, &nonce_values, &counter_info));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreRenewalRequest) {
|
||||
@@ -446,12 +543,27 @@ TEST(OdkTest, PrepareCoreProvisioningRequest) {
|
||||
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};
|
||||
EXPECT_EQ(
|
||||
OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
provisioning_message, sizeof(provisioning_message),
|
||||
&core_message_length, &nonce_values, device_id, sizeof(device_id)));
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
memset(&counter_info, 0, sizeof(counter_info));
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
provisioning_message, sizeof(provisioning_message),
|
||||
&core_message_length, &nonce_values, &counter_info));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreProvisioning40Request) {
|
||||
uint8_t provisioning_message[ODK_PROVISIONING40_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(provisioning_message);
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
memset(&counter_info, 0, sizeof(counter_info));
|
||||
uint8_t device_info[ODK_DEVICE_INFO_LEN_MAX] = {0};
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreProvisioning40Request(
|
||||
provisioning_message, sizeof(provisioning_message),
|
||||
&core_message_length, &nonce_values, device_info,
|
||||
sizeof(device_info), &counter_info));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreRenewedProvisioningRequest) {
|
||||
@@ -469,17 +581,19 @@ TEST(OdkTest, PrepareCoreRenewedProvisioningRequest) {
|
||||
OEMCrypto_RenewalACert, renewal_data, sizeof(renewal_data)));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreProvisioningRequestDeviceId) {
|
||||
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
TEST(OdkTest, PrepareCoreProvisioning40RequestDeviceInfo) {
|
||||
uint8_t provisioning_message[ODK_PROVISIONING40_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};
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
memset(&counter_info, 0, sizeof(counter_info));
|
||||
uint8_t device_info_invalid[ODK_DEVICE_INFO_LEN_MAX + 1] = {0};
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
ODK_PrepareCoreProvisioning40Request(
|
||||
provisioning_message, sizeof(provisioning_message),
|
||||
&core_message_length, &nonce_values, device_id_invalid,
|
||||
sizeof(device_id_invalid)));
|
||||
&core_message_length, &nonce_values, device_info_invalid,
|
||||
sizeof(device_info_invalid), &counter_info));
|
||||
}
|
||||
|
||||
TEST(OdkTest, PrepareCoreRenewedProvisioningRequestDeviceId) {
|
||||
@@ -514,13 +628,36 @@ TEST(OdkTest, PrepareCoreRenewedProvisioningRequestRenewalDataInvalid) {
|
||||
|
||||
// Serialize and de-serialize license request
|
||||
TEST(OdkTest, LicenseRequestRoundtrip) {
|
||||
std::vector<ODK_Field> empty;
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
counter_info.master_generation_number = 0x12345678abcdffff;
|
||||
counter_info.provisioning_count = 12;
|
||||
counter_info.license_count = 50;
|
||||
counter_info.decrypt_count = 340;
|
||||
counter_info.major_version = ODK_MAJOR_VERSION;
|
||||
counter_info.minor_version = ODK_MINOR_VERSION;
|
||||
counter_info.patch_version = 4;
|
||||
memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor));
|
||||
memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model));
|
||||
memset(counter_info.extra, 0xee, sizeof(counter_info.extra));
|
||||
std::vector<ODK_Field> extra_fields = {
|
||||
{ODK_MESSAGECOUNTER, &counter_info, "counter_info"},
|
||||
};
|
||||
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
|
||||
ODK_NonceValues* nonce_values) {
|
||||
return ODK_PrepareCoreLicenseRequest(buf, SIZE_MAX, size, nonce_values);
|
||||
return ODK_PrepareCoreLicenseRequest(buf, SIZE_MAX, size, nonce_values,
|
||||
&counter_info);
|
||||
};
|
||||
auto kdo_parse_func = CoreLicenseRequestFromMessage;
|
||||
ValidateRequest<ODK_LicenseRequest>(ODK_License_Request_Type, empty,
|
||||
auto kdo_parse_func = [&](const std::string& oemcrypto_core_message,
|
||||
ODK_LicenseRequest* core_license_request) {
|
||||
bool ok = CoreLicenseRequestFromMessage(oemcrypto_core_message,
|
||||
core_license_request);
|
||||
if (!ok) return false;
|
||||
|
||||
ok = CheckCounterInfoIsEqual(&counter_info,
|
||||
&core_license_request->counter_info);
|
||||
return ok;
|
||||
};
|
||||
ValidateRequest<ODK_LicenseRequest>(ODK_License_Request_Type, extra_fields,
|
||||
odk_prepare_func, kdo_parse_func);
|
||||
}
|
||||
|
||||
@@ -550,23 +687,38 @@ TEST(OdkTest, RenewalRequestRoundtrip) {
|
||||
}
|
||||
|
||||
TEST(OdkTest, ProvisionRequestRoundtrip) {
|
||||
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);
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
counter_info.master_generation_number = 0x12345678abcdffff;
|
||||
counter_info.provisioning_count = 12;
|
||||
counter_info.license_count = 50;
|
||||
counter_info.decrypt_count = 340;
|
||||
counter_info.major_version = ODK_MAJOR_VERSION;
|
||||
counter_info.minor_version = ODK_MINOR_VERSION;
|
||||
counter_info.patch_version = 4;
|
||||
memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor));
|
||||
memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model));
|
||||
memset(counter_info.extra, 0xee, sizeof(counter_info.extra));
|
||||
// Fake device_id_length for older servers, since we removed device id from
|
||||
// the v18 request
|
||||
uint32_t fake_device_id_length = 64;
|
||||
std::vector<ODK_Field> extra_fields = {
|
||||
{ODK_UINT32, &device_id_length, "device_id_length"},
|
||||
{ODK_DEVICEID, device_id, "device_id"},
|
||||
{ODK_UINT32, &(fake_device_id_length), "fake_device_id_length"},
|
||||
{ODK_MESSAGECOUNTER, &counter_info, "counter_info"},
|
||||
};
|
||||
|
||||
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
return ODK_PrepareCoreProvisioningRequest(buf, SIZE_MAX, size, nonce_values,
|
||||
device_id, device_id_length);
|
||||
&counter_info);
|
||||
};
|
||||
auto kdo_parse_func =
|
||||
[&](const std::string& oemcrypto_core_message,
|
||||
ODK_ProvisioningRequest* core_provisioning_request) {
|
||||
bool ok = CoreProvisioningRequestFromMessage(oemcrypto_core_message,
|
||||
core_provisioning_request);
|
||||
if (!ok) return false;
|
||||
ok = CheckCounterInfoIsEqual(&counter_info,
|
||||
&core_provisioning_request->counter_info);
|
||||
return ok;
|
||||
};
|
||||
ValidateRequest<ODK_ProvisioningRequest>(ODK_Provisioning_Request_Type,
|
||||
@@ -574,6 +726,47 @@ TEST(OdkTest, ProvisionRequestRoundtrip) {
|
||||
kdo_parse_func);
|
||||
}
|
||||
|
||||
TEST(OdkTest, ProvisionRequest40Roundtrip) {
|
||||
uint32_t device_info_length = ODK_DEVICE_INFO_LEN_MAX / 2;
|
||||
uint8_t device_info[ODK_DEVICE_INFO_LEN_MAX] = {0};
|
||||
memset(device_info, 0xaa, device_info_length);
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
counter_info.master_generation_number = 0x12345678abcdffff;
|
||||
counter_info.provisioning_count = 12;
|
||||
counter_info.license_count = 50;
|
||||
counter_info.decrypt_count = 340;
|
||||
counter_info.major_version = ODK_MAJOR_VERSION;
|
||||
counter_info.minor_version = ODK_MINOR_VERSION;
|
||||
counter_info.patch_version = 4;
|
||||
memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor));
|
||||
memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model));
|
||||
memset(counter_info.extra, 0xee, sizeof(counter_info.extra));
|
||||
std::vector<ODK_Field> extra_fields = {
|
||||
{ODK_UINT32, &device_info_length, "device_info_length"},
|
||||
{ODK_DEVICEINFO, device_info, "device_info"},
|
||||
{ODK_MESSAGECOUNTER, &counter_info, "counter_info"},
|
||||
};
|
||||
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
return ODK_PrepareCoreProvisioning40Request(
|
||||
buf, SIZE_MAX, size, nonce_values, device_info, device_info_length,
|
||||
&counter_info);
|
||||
};
|
||||
auto kdo_parse_func =
|
||||
[&](const std::string& oemcrypto_core_message,
|
||||
ODK_Provisioning40Request* core_provisioning_request) {
|
||||
bool ok = CoreProvisioning40RequestFromMessage(
|
||||
oemcrypto_core_message, core_provisioning_request);
|
||||
if (!ok) return false;
|
||||
ok = CheckCounterInfoIsEqual(&counter_info,
|
||||
&core_provisioning_request->counter_info);
|
||||
return ok;
|
||||
};
|
||||
ValidateRequest<ODK_Provisioning40Request>(ODK_Provisioning40_Request_Type,
|
||||
extra_fields, odk_prepare_func,
|
||||
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};
|
||||
@@ -618,9 +811,9 @@ 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.timer_limits),
|
||||
params.usage_entry_present, 0, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(OEMCrypto_ERROR_INVALID_NONCE, err);
|
||||
delete[] buf;
|
||||
}
|
||||
@@ -635,9 +828,9 @@ 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.timer_limits),
|
||||
params.usage_entry_present, 0, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
|
||||
delete[] buf;
|
||||
}
|
||||
@@ -653,9 +846,9 @@ TEST(OdkTest, ParseLicenseNullSubstring) {
|
||||
&buf_size);
|
||||
OEMCryptoResult result = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
params.usage_entry_present, 0, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, result);
|
||||
delete[] buf;
|
||||
}
|
||||
@@ -671,9 +864,9 @@ TEST(OdkTest, ParseLicenseErrorSubstringOffset) {
|
||||
&buf_size);
|
||||
OEMCryptoResult err = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
params.usage_entry_present, 0, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
|
||||
delete[] buf;
|
||||
|
||||
@@ -687,9 +880,9 @@ TEST(OdkTest, ParseLicenseErrorSubstringOffset) {
|
||||
&buf_size);
|
||||
err = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, &(params.timer_limits),
|
||||
params.usage_entry_present, 0, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
|
||||
delete[] buf;
|
||||
}
|
||||
@@ -701,7 +894,10 @@ TEST(OdkTest, ParseRenewalErrorTimer) {
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
&buf_size);
|
||||
params.clock_values.time_of_renewal_request = 0;
|
||||
// Set the time for the last renewal request, as seen in clock_values, to be
|
||||
// after the time in the request.
|
||||
// TODO: b/290249855 - This is reversed. It should be +5.
|
||||
params.clock_values.time_of_renewal_request = params.playback_clock - 5;
|
||||
OEMCryptoResult err = ODK_ParseRenewal(
|
||||
buf, buf_size, buf_size, &(params.core_message.nonce_values),
|
||||
params.system_time, &(params.timer_limits), &(params.clock_values),
|
||||
@@ -710,20 +906,50 @@ TEST(OdkTest, ParseRenewalErrorTimer) {
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
TEST(OdkTest, ParsePrivisioningErrorDeviceId) {
|
||||
ODK_ProvisioningResponseParams params;
|
||||
ODK_SetDefaultProvisioningResponseParams(¶ms);
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
&buf_size);
|
||||
// temporarily mess up with device_id
|
||||
params.device_id[0] = 0;
|
||||
OEMCryptoResult err = ODK_ParseProvisioning(
|
||||
buf, buf_size + 16, buf_size, &(params.core_message.nonce_values),
|
||||
params.device_id, params.device_id_length, &(params.parsed_provisioning));
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
|
||||
delete[] buf;
|
||||
TEST(OdkTest, ProvisionResponseFromProto) {
|
||||
std::string serialized_provisioning_resp;
|
||||
EXPECT_NO_FATAL_FAILURE(
|
||||
SetDefaultSerializedProvisioningResponse(&serialized_provisioning_resp));
|
||||
ODK_ProvisioningRequest core_request = {
|
||||
.api_minor_version = ODK_MINOR_VERSION,
|
||||
.api_major_version = ODK_MAJOR_VERSION,
|
||||
.nonce = 0xdeadbeef,
|
||||
.session_id = 0xcafebabe,
|
||||
};
|
||||
const CoreMessageFeatures features =
|
||||
CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION);
|
||||
std::string oemcrypto_core_message;
|
||||
EXPECT_TRUE(CreateCoreProvisioningResponseFromProto(
|
||||
features, serialized_provisioning_resp, core_request,
|
||||
OEMCrypto_RSA_Private_Key, &oemcrypto_core_message));
|
||||
}
|
||||
|
||||
// Verify de-serialize common request.
|
||||
TEST(OdkTest, ParseCoreCommonRequestFromMessage) {
|
||||
std::string serialized_provisioning_resp;
|
||||
EXPECT_NO_FATAL_FAILURE(
|
||||
SetDefaultSerializedProvisioningResponse(&serialized_provisioning_resp));
|
||||
ODK_ProvisioningRequest core_request = {
|
||||
.api_minor_version = ODK_MINOR_VERSION,
|
||||
.api_major_version = ODK_MAJOR_VERSION,
|
||||
.nonce = 0xdeadbeef,
|
||||
.session_id = 0xcafebabe,
|
||||
};
|
||||
const CoreMessageFeatures features =
|
||||
CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION);
|
||||
std::string oemcrypto_core_message;
|
||||
EXPECT_TRUE(CreateCoreProvisioningResponseFromProto(
|
||||
features, serialized_provisioning_resp, core_request,
|
||||
OEMCrypto_RSA_Private_Key, &oemcrypto_core_message));
|
||||
ODK_CommonRequest odk_common_request;
|
||||
ASSERT_TRUE(CoreCommonRequestFromMessage(oemcrypto_core_message,
|
||||
&odk_common_request));
|
||||
EXPECT_EQ(odk_common_request.message_type, 6u);
|
||||
EXPECT_EQ(odk_common_request.message_length, 48u);
|
||||
EXPECT_EQ(odk_common_request.api_minor_version, ODK_MINOR_VERSION);
|
||||
EXPECT_EQ(odk_common_request.api_major_version, ODK_MAJOR_VERSION);
|
||||
EXPECT_EQ(odk_common_request.nonce, 0xdeadbeef);
|
||||
EXPECT_EQ(odk_common_request.session_id, 0xcafebabe);
|
||||
}
|
||||
|
||||
class OdkVersionTest : public ::testing::Test,
|
||||
@@ -735,8 +961,12 @@ 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);
|
||||
if (GetParam().maximum_major_version > 0) {
|
||||
features_ = CoreMessageFeatures::DefaultFeatures(
|
||||
GetParam().maximum_major_version);
|
||||
} else {
|
||||
features_ = CoreMessageFeatures::kDefaultFeatures;
|
||||
}
|
||||
}
|
||||
CoreMessageFeatures features_;
|
||||
};
|
||||
@@ -756,17 +986,36 @@ TEST_P(OdkVersionTest, LicenseResponseRoundtrip) {
|
||||
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, &(params.timer_limits),
|
||||
params.usage_entry_present, 0, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license));
|
||||
&(params.parsed_license), nullptr);
|
||||
};
|
||||
|
||||
ODK_Packing_ParsedLicense parsed_license;
|
||||
parsed_license.enc_mac_keys_iv = params.parsed_license.enc_mac_keys_iv;
|
||||
parsed_license.enc_mac_keys = params.parsed_license.enc_mac_keys;
|
||||
parsed_license.pst = params.parsed_license.pst;
|
||||
parsed_license.srm_restriction_data =
|
||||
params.parsed_license.srm_restriction_data;
|
||||
parsed_license.license_type = params.parsed_license.license_type;
|
||||
parsed_license.nonce_required = params.parsed_license.nonce_required;
|
||||
parsed_license.timer_limits = params.parsed_license.timer_limits;
|
||||
parsed_license.watermarking = params.parsed_license.watermarking;
|
||||
parsed_license.dtcp2_required = params.parsed_license.dtcp2_required;
|
||||
parsed_license.renewal_delay_base = params.parsed_license.renewal_delay_base;
|
||||
parsed_license.key_array_length = params.parsed_license.key_array_length;
|
||||
std::vector<OEMCrypto_KeyObject> key_array;
|
||||
for (size_t i = 0; i < params.parsed_license.key_array_length; i++) {
|
||||
key_array.push_back(params.parsed_license.key_array[i]);
|
||||
}
|
||||
parsed_license.key_array = key_array.data();
|
||||
const std::string request_hash_string(
|
||||
reinterpret_cast<const char*>(request_hash_read),
|
||||
sizeof(request_hash_read));
|
||||
auto kdo_prepare_func = [&](const ODK_LicenseRequest& core_request,
|
||||
std::string* oemcrypto_core_message) {
|
||||
return CreateCoreLicenseResponse(features_, params.parsed_license,
|
||||
core_request, request_hash_string,
|
||||
return CreateCoreLicenseResponse(features_, parsed_license, core_request,
|
||||
request_hash_string,
|
||||
oemcrypto_core_message);
|
||||
};
|
||||
ValidateResponse<ODK_LicenseRequest>(GetParam(), &(params.core_message),
|
||||
@@ -774,6 +1023,84 @@ TEST_P(OdkVersionTest, LicenseResponseRoundtrip) {
|
||||
kdo_prepare_func);
|
||||
}
|
||||
|
||||
// Serialize and de-serialize license response with more keys than
|
||||
// ODK_MAX_NUM_KEYS.
|
||||
TEST_P(OdkVersionTest, LicenseResponseRoundtripMoreThanMaxKeys) {
|
||||
ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms,
|
||||
GetParam().response_major_version);
|
||||
SetRequestVersion(¶ms);
|
||||
// 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));
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
&buf_size);
|
||||
|
||||
uint8_t* zero = new uint8_t[buf_size]{};
|
||||
size_t bytes_read = 0;
|
||||
// zero-out input
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_IterFields(ODK_READ, zero, buf_size, &bytes_read,
|
||||
params.extra_fields));
|
||||
|
||||
// Parse buf with odk
|
||||
const OEMCryptoResult parse_result = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, 0, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, parse_result);
|
||||
|
||||
size_t size_out = 0;
|
||||
if (parse_result != OEMCrypto_SUCCESS) {
|
||||
ODK_IterFields(ODK_FieldMode::ODK_DUMP, buf, buf_size, &size_out,
|
||||
params.extra_fields);
|
||||
}
|
||||
|
||||
ODK_Packing_ParsedLicense parsed_license;
|
||||
parsed_license.enc_mac_keys_iv = params.parsed_license.enc_mac_keys_iv;
|
||||
parsed_license.enc_mac_keys = params.parsed_license.enc_mac_keys;
|
||||
parsed_license.pst = params.parsed_license.pst;
|
||||
parsed_license.srm_restriction_data =
|
||||
params.parsed_license.srm_restriction_data;
|
||||
parsed_license.license_type = params.parsed_license.license_type;
|
||||
parsed_license.nonce_required = params.parsed_license.nonce_required;
|
||||
parsed_license.timer_limits = params.parsed_license.timer_limits;
|
||||
parsed_license.watermarking = params.parsed_license.watermarking;
|
||||
parsed_license.dtcp2_required = params.parsed_license.dtcp2_required;
|
||||
parsed_license.renewal_delay_base = params.parsed_license.renewal_delay_base;
|
||||
parsed_license.key_array_length = ODK_MAX_NUM_KEYS + 1;
|
||||
std::vector<OEMCrypto_KeyObject> key_array;
|
||||
for (size_t i = 0; i < ODK_MAX_NUM_KEYS + 1; i++) {
|
||||
OEMCrypto_KeyObject key = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
|
||||
key_array.push_back(key);
|
||||
}
|
||||
parsed_license.key_array = key_array.data();
|
||||
const std::string request_hash_string(
|
||||
reinterpret_cast<const char*>(request_hash_read),
|
||||
sizeof(request_hash_read));
|
||||
|
||||
// serialize odk output to oemcrypto_core_message
|
||||
std::string oemcrypto_core_message;
|
||||
ODK_LicenseRequest core_request = {};
|
||||
core_request.api_major_version = GetParam().request_major_version;
|
||||
core_request.api_minor_version = GetParam().request_minor_version;
|
||||
core_request.nonce = params.core_message.nonce_values.nonce;
|
||||
core_request.session_id = params.core_message.nonce_values.session_id;
|
||||
bool result =
|
||||
CreateCoreLicenseResponse(features_, parsed_license, core_request,
|
||||
request_hash_string, &oemcrypto_core_message);
|
||||
EXPECT_FALSE(result);
|
||||
|
||||
delete[] buf;
|
||||
delete[] zero;
|
||||
}
|
||||
|
||||
TEST_P(OdkVersionTest, RenewalResponseRoundtrip) {
|
||||
ODK_RenewalResponseParams params;
|
||||
ODK_SetDefaultRenewalResponseParams(¶ms);
|
||||
@@ -806,7 +1133,8 @@ TEST_P(OdkVersionTest, RenewalResponseRoundtrip) {
|
||||
|
||||
TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) {
|
||||
ODK_ProvisioningResponseParams params;
|
||||
ODK_SetDefaultProvisioningResponseParams(¶ms);
|
||||
ODK_SetDefaultProvisioningResponseParams(¶ms,
|
||||
GetParam().response_major_version);
|
||||
SetRequestVersion(¶ms);
|
||||
// save a copy of params.device_id as it will be zero out during the test
|
||||
const uint32_t device_id_length = params.device_id_length;
|
||||
@@ -821,8 +1149,12 @@ TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) {
|
||||
};
|
||||
auto kdo_prepare_func = [&](ODK_ProvisioningRequest& core_request,
|
||||
std::string* oemcrypto_core_message) {
|
||||
// use device_id for V17 and V16
|
||||
core_request.device_id.assign(reinterpret_cast<char*>(device_id),
|
||||
device_id_length);
|
||||
// use counter info for V18
|
||||
memcpy(&core_request.counter_info, ¶ms.counter_info,
|
||||
sizeof(params.counter_info));
|
||||
return CreateCoreProvisioningResponse(features_, params.parsed_provisioning,
|
||||
core_request, oemcrypto_core_message);
|
||||
};
|
||||
@@ -831,12 +1163,30 @@ TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) {
|
||||
kdo_prepare_func);
|
||||
}
|
||||
|
||||
TEST_P(OdkVersionTest, Provision40ResponseRoundtrip) {
|
||||
ODK_Provisioning40ResponseParams params;
|
||||
ODK_SetDefaultProvisioning40ResponseParams(¶ms);
|
||||
SetRequestVersion(¶ms);
|
||||
|
||||
auto odk_parse_func = [&](const uint8_t* buf, size_t size) {
|
||||
OEMCryptoResult err = ODK_ParseProvisioning40(
|
||||
buf, size + 16, size, &(params.core_message.nonce_values));
|
||||
return err;
|
||||
};
|
||||
auto kdo_prepare_func = [&](ODK_Provisioning40Request& core_request,
|
||||
std::string* oemcrypto_core_message) {
|
||||
return CreateCoreProvisioning40Response(features_, core_request,
|
||||
oemcrypto_core_message);
|
||||
};
|
||||
ValidateResponse<ODK_Provisioning40Request>(
|
||||
GetParam(), &(params.core_message), params.extra_fields, odk_parse_func,
|
||||
kdo_prepare_func);
|
||||
}
|
||||
|
||||
// If the minor version is positive, we can test an older minor version.
|
||||
const uint16_t kOldMinor = ODK_MINOR_VERSION > 0 ? ODK_MINOR_VERSION - 1 : 0;
|
||||
// Similarly, if this isn't the first major version, we can test an older major
|
||||
// version.
|
||||
// TODO(b/163416999): Remove it in the future. This will be unecessarily
|
||||
// complicated after we upgrade to version 17.
|
||||
const uint16_t kOldMajor = ODK_MAJOR_VERSION > ODK_FIRST_VERSION
|
||||
? ODK_MAJOR_VERSION - 1
|
||||
: ODK_FIRST_VERSION;
|
||||
@@ -862,16 +1212,26 @@ std::vector<VersionParameters> TestCases() {
|
||||
{ODK_MAJOR_VERSION, kOldMajor, kOldMajorMinor, kOldMajor, kOldMajorMinor},
|
||||
// If the server is restricted to v16, then the response can be at
|
||||
// most 16.5
|
||||
// These tests cases must be updated whenever we roll the minor version
|
||||
// number.
|
||||
{16, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 16, 5},
|
||||
{17, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 17, 2},
|
||||
{18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 3},
|
||||
// Here are some known good versions. Make extra sure they work.
|
||||
{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},
|
||||
{ODK_MAJOR_VERSION, 16, 3, 16, 3},
|
||||
{ODK_MAJOR_VERSION, 16, 4, 16, 4},
|
||||
{ODK_MAJOR_VERSION, 16, 5, 16, 5},
|
||||
{ODK_MAJOR_VERSION, 17, 1, 17, 1},
|
||||
{ODK_MAJOR_VERSION, 17, 2, 17, 2},
|
||||
{ODK_MAJOR_VERSION, 18, 1, 18, 1},
|
||||
{ODK_MAJOR_VERSION, 18, 2, 18, 2},
|
||||
{ODK_MAJOR_VERSION, 18, 3, 18, 3},
|
||||
{0, 16, 3, 16, 3},
|
||||
{0, 16, 4, 16, 4},
|
||||
{0, 16, 5, 16, 5},
|
||||
{0, 17, 1, 17, 1},
|
||||
{0, 17, 2, 17, 2},
|
||||
{0, 18, 3, 18, 3}, // Change to 19 when the default version is updated.
|
||||
};
|
||||
return test_cases;
|
||||
}
|
||||
@@ -887,13 +1247,20 @@ TEST(OdkSizeTest, LicenseRequest) {
|
||||
uint16_t api_major_version = 0;
|
||||
uint32_t nonce = 0;
|
||||
uint32_t session_id = 0;
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
memset(&counter_info, 0, sizeof(counter_info));
|
||||
ODK_NonceValues nonce_values{api_minor_version, api_major_version, nonce,
|
||||
session_id};
|
||||
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
|
||||
ODK_PrepareCoreLicenseRequest(message, message_length,
|
||||
&core_message_length, &nonce_values));
|
||||
&core_message_length, &nonce_values,
|
||||
&counter_info));
|
||||
// the core_message_length should be appropriately set
|
||||
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE, core_message_length);
|
||||
if (nonce_values.api_major_version > 17) {
|
||||
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE, core_message_length);
|
||||
} else {
|
||||
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE_V17, core_message_length);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OdkSizeTest, RenewalRequest) {
|
||||
@@ -948,15 +1315,20 @@ TEST(OdkSizeTest, ProvisioningRequest) {
|
||||
uint16_t api_major_version = 0;
|
||||
uint32_t nonce = 0;
|
||||
uint32_t session_id = 0;
|
||||
uint32_t device_id_length = 0;
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
memset(&counter_info, 0, sizeof(counter_info));
|
||||
ODK_NonceValues nonce_values{api_minor_version, api_major_version, nonce,
|
||||
session_id};
|
||||
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
message, message_length, &core_message_length, &nonce_values,
|
||||
nullptr, device_id_length));
|
||||
ODK_PrepareCoreProvisioningRequest(message, message_length,
|
||||
&core_message_length,
|
||||
&nonce_values, &counter_info));
|
||||
// the core_message_length should be appropriately set
|
||||
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE, core_message_length);
|
||||
if (nonce_values.api_major_version > 17) {
|
||||
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE, core_message_length);
|
||||
} else {
|
||||
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE_V17, core_message_length);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the version string contains the right version numbers.
|
||||
@@ -970,6 +1342,37 @@ TEST(OdkTest, CheckReleaseVersion) {
|
||||
<< "Version mismatch in odk_structs.h";
|
||||
}
|
||||
|
||||
TEST(OdkOverflowTest, SubtractU64) {
|
||||
uint64_t result = 0;
|
||||
EXPECT_FALSE(odk_sub_overflow_u64(10, 5, &result));
|
||||
EXPECT_EQ(result, static_cast<uint64_t>(10 - 5));
|
||||
EXPECT_TRUE(odk_sub_overflow_u64(5, 10, &result));
|
||||
}
|
||||
|
||||
TEST(OdkOverflowTest, AddU64) {
|
||||
uint64_t result = 0;
|
||||
EXPECT_FALSE(odk_add_overflow_u64(2, 2, &result));
|
||||
EXPECT_EQ(result, static_cast<uint64_t>(2 + 2));
|
||||
EXPECT_TRUE(odk_add_overflow_u64(0xffffffffffffffff, 1, &result));
|
||||
EXPECT_TRUE(odk_add_overflow_u64(1, 0xffffffffffffffff, &result));
|
||||
}
|
||||
|
||||
TEST(OdkOverflowTest, AddUX) {
|
||||
size_t result = 0;
|
||||
EXPECT_FALSE(odk_add_overflow_ux(2, 2, &result));
|
||||
EXPECT_EQ(result, static_cast<uint64_t>(2 + 2));
|
||||
EXPECT_TRUE(odk_add_overflow_ux(SIZE_MAX, 1, &result));
|
||||
EXPECT_TRUE(odk_add_overflow_ux(1, SIZE_MAX, &result));
|
||||
}
|
||||
|
||||
TEST(OdkOverflowTest, MultiplyUX) {
|
||||
size_t result = 0;
|
||||
EXPECT_FALSE(odk_mul_overflow_ux(2, 7, &result));
|
||||
EXPECT_EQ(result, static_cast<uint64_t>(2 * 7));
|
||||
EXPECT_TRUE(odk_mul_overflow_ux(SIZE_MAX >> 1, 4, &result));
|
||||
EXPECT_TRUE(odk_mul_overflow_ux(4, SIZE_MAX >> 1, &result));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace wvodk_test
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
{
|
||||
'sources': [
|
||||
'odk_golden_v16.cpp',
|
||||
'odk_golden_v17.cpp',
|
||||
'odk_golden_v18.cpp',
|
||||
'odk_test.cpp',
|
||||
'odk_test_helper.cpp',
|
||||
'odk_test_helper.h',
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -75,6 +78,7 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params,
|
||||
.length = 3,
|
||||
.data = {0, 0, 0},
|
||||
}},
|
||||
.renewal_delay_base = OEMCrypto_License_Start,
|
||||
.key_array_length = 3,
|
||||
.key_array =
|
||||
{
|
||||
@@ -203,6 +207,11 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params,
|
||||
".cmi_descriptor_data"});
|
||||
}
|
||||
}
|
||||
if (odk_major_version >= 18) {
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT32, &(params->parsed_license.renewal_delay_base),
|
||||
".renewal_delay_base"});
|
||||
}
|
||||
params->extra_fields.push_back({ODK_UINT32,
|
||||
&(params->parsed_license.key_array_length),
|
||||
".key_array_length"});
|
||||
@@ -288,7 +297,7 @@ void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params) {
|
||||
}
|
||||
|
||||
void ODK_SetDefaultProvisioningResponseParams(
|
||||
ODK_ProvisioningResponseParams* params) {
|
||||
ODK_ProvisioningResponseParams* params, uint32_t odk_major_version) {
|
||||
ODK_SetDefaultCoreFields(&(params->core_message),
|
||||
ODK_Provisioning_Response_Type);
|
||||
params->device_id_length = ODK_DEVICE_ID_LEN_MAX / 2;
|
||||
@@ -301,17 +310,34 @@ void ODK_SetDefaultProvisioningResponseParams(
|
||||
.enc_private_key_iv = {.offset = 2, .length = 3},
|
||||
.encrypted_message_key = {.offset = 4, .length = 5},
|
||||
};
|
||||
params->extra_fields = {
|
||||
{ODK_UINT32, &(params->device_id_length), "device_id_length"},
|
||||
{ODK_DEVICEID, params->device_id, "device_id"},
|
||||
{ODK_UINT32, &(params->parsed_provisioning).key_type, "key_type"},
|
||||
|
||||
params->extra_fields = {};
|
||||
// V17 uses device_id
|
||||
if (odk_major_version <= 17) {
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT32, &(params->device_id_length), "device_id_length"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_DEVICEID, params->device_id, "device_id"});
|
||||
}
|
||||
|
||||
params->extra_fields.push_back(
|
||||
{ODK_UINT32, &(params->parsed_provisioning).key_type, "key_type"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_provisioning).enc_private_key,
|
||||
"enc_private_key"},
|
||||
"enc_private_key"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_provisioning).enc_private_key_iv,
|
||||
"enc_private_key_iv"},
|
||||
"enc_private_key_iv"});
|
||||
params->extra_fields.push_back(
|
||||
{ODK_SUBSTRING, &(params->parsed_provisioning).encrypted_message_key,
|
||||
"encrypted_message_key"},
|
||||
};
|
||||
"encrypted_message_key"});
|
||||
}
|
||||
|
||||
void ODK_SetDefaultProvisioning40ResponseParams(
|
||||
ODK_Provisioning40ResponseParams* params) {
|
||||
ODK_SetDefaultCoreFields(&(params->core_message),
|
||||
ODK_Provisioning_Response_Type);
|
||||
params->extra_fields = {};
|
||||
}
|
||||
|
||||
size_t ODK_FieldLength(ODK_FieldType type) {
|
||||
@@ -330,6 +356,10 @@ size_t ODK_FieldLength(ODK_FieldType type) {
|
||||
return sizeof(uint32_t) + sizeof(uint32_t);
|
||||
case ODK_DEVICEID:
|
||||
return ODK_DEVICE_ID_LEN_MAX;
|
||||
case ODK_MESSAGECOUNTER:
|
||||
return ODK_MESSAGECOUNTERINFO_SIZE;
|
||||
case ODK_DEVICEINFO:
|
||||
return ODK_DEVICE_INFO_LEN_MAX;
|
||||
case ODK_RENEWALDATA:
|
||||
return ODK_KEYBOX_RENEWAL_DATA_SIZE;
|
||||
case ODK_HASH:
|
||||
@@ -343,6 +373,9 @@ size_t ODK_AllocSize(ODK_FieldType type) {
|
||||
if (type == ODK_SUBSTRING) {
|
||||
return sizeof(OEMCrypto_Substring);
|
||||
}
|
||||
if (type == ODK_MESSAGECOUNTER) {
|
||||
return sizeof(ODK_MessageCounterInfo);
|
||||
}
|
||||
return ODK_FieldLength(type);
|
||||
}
|
||||
|
||||
@@ -388,6 +421,7 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field) {
|
||||
break;
|
||||
}
|
||||
case ODK_DEVICEID:
|
||||
case ODK_DEVICEINFO:
|
||||
case ODK_RENEWALDATA:
|
||||
case ODK_HASH: {
|
||||
const size_t field_len = ODK_FieldLength(field->type);
|
||||
@@ -396,6 +430,27 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field) {
|
||||
|
||||
break;
|
||||
}
|
||||
case ODK_MESSAGECOUNTER: {
|
||||
// Size required in field->value, which may get padding from the compiler.
|
||||
const size_t src_len = ODK_AllocSize(field->type);
|
||||
// Size taken up in serialized message buffer, which is tightly packed.
|
||||
const size_t dest_len = ODK_FieldLength(field->type);
|
||||
const uint8_t* const write_src = static_cast<uint8_t*>(field->value);
|
||||
|
||||
// Copy data from field to buf, fixing endian-ness
|
||||
ODK_MessageCounterInfo info;
|
||||
memcpy(&info, write_src, src_len);
|
||||
info.master_generation_number =
|
||||
oemcrypto_htobe64(info.master_generation_number);
|
||||
info.provisioning_count = oemcrypto_htobe32(info.provisioning_count);
|
||||
info.license_count = oemcrypto_htobe32(info.license_count);
|
||||
info.decrypt_count = oemcrypto_htobe32(info.decrypt_count);
|
||||
info.major_version = oemcrypto_htobe16(info.major_version);
|
||||
info.minor_version = oemcrypto_htobe16(info.minor_version);
|
||||
info.patch_version = oemcrypto_htobe16(info.patch_version);
|
||||
memcpy(buf, &info, dest_len);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
@@ -448,6 +503,7 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf,
|
||||
break;
|
||||
}
|
||||
case ODK_DEVICEID:
|
||||
case ODK_DEVICEINFO:
|
||||
case ODK_RENEWALDATA:
|
||||
case ODK_HASH: {
|
||||
const size_t field_len = ODK_FieldLength(field->type);
|
||||
@@ -455,6 +511,55 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf,
|
||||
memcpy(id, buf, field_len);
|
||||
break;
|
||||
}
|
||||
case ODK_MESSAGECOUNTER: {
|
||||
// Size required in field->value, which may get padding from the compiler.
|
||||
const size_t dest_len = ODK_AllocSize(field->type);
|
||||
// Size taken up in serialized message buffer, which is tightly packed.
|
||||
const size_t src_len = ODK_FieldLength(field->type);
|
||||
uint8_t* const read_dest = static_cast<uint8_t*>(field->value);
|
||||
|
||||
// Copy data from buf to field, fixing endian-ness
|
||||
uint8_t temp_buf[sizeof(ODK_MessageCounterInfo)] = {0};
|
||||
memcpy(temp_buf, buf, src_len);
|
||||
|
||||
size_t index = 0;
|
||||
ODK_MessageCounterInfo info;
|
||||
uint64_t* u64 = reinterpret_cast<uint64_t*>(&temp_buf[index]);
|
||||
info.master_generation_number = oemcrypto_be64toh(*u64);
|
||||
index += sizeof(uint64_t);
|
||||
|
||||
uint32_t* u32 = reinterpret_cast<uint32_t*>(&temp_buf[index]);
|
||||
info.provisioning_count = oemcrypto_be32toh(*u32);
|
||||
index += sizeof(uint32_t);
|
||||
|
||||
u32 = reinterpret_cast<uint32_t*>(&temp_buf[index]);
|
||||
info.license_count = oemcrypto_be32toh(*u32);
|
||||
index += sizeof(uint32_t);
|
||||
|
||||
u32 = reinterpret_cast<uint32_t*>(&temp_buf[index]);
|
||||
info.decrypt_count = oemcrypto_be32toh(*u32);
|
||||
index += sizeof(uint32_t);
|
||||
|
||||
uint16_t* u16 = reinterpret_cast<uint16_t*>(&temp_buf[index]);
|
||||
info.major_version = oemcrypto_be16toh(*u16);
|
||||
index += sizeof(uint16_t);
|
||||
|
||||
u16 = reinterpret_cast<uint16_t*>(&temp_buf[index]);
|
||||
info.minor_version = oemcrypto_be16toh(*u16);
|
||||
index += sizeof(uint16_t);
|
||||
|
||||
u16 = reinterpret_cast<uint16_t*>(&temp_buf[index]);
|
||||
info.patch_version = oemcrypto_be16toh(*u16);
|
||||
index += sizeof(uint16_t);
|
||||
|
||||
memcpy(info.soc_vendor, &temp_buf[index], sizeof(info.soc_vendor));
|
||||
index += sizeof(info.soc_vendor);
|
||||
memcpy(info.chipset_model, &temp_buf[index], sizeof(info.chipset_model));
|
||||
index += sizeof(info.chipset_model);
|
||||
memcpy(info.extra, &temp_buf[index], sizeof(info.extra));
|
||||
memcpy(read_dest, &info, dest_len);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
@@ -508,6 +613,8 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf,
|
||||
break;
|
||||
}
|
||||
case ODK_DEVICEID:
|
||||
case ODK_MESSAGECOUNTER:
|
||||
case ODK_DEVICEINFO:
|
||||
case ODK_RENEWALDATA:
|
||||
case ODK_HASH: {
|
||||
const size_t field_len = ODK_FieldLength(field->type);
|
||||
|
||||
@@ -21,6 +21,8 @@ enum ODK_FieldType {
|
||||
ODK_UINT64,
|
||||
ODK_SUBSTRING,
|
||||
ODK_DEVICEID,
|
||||
ODK_DEVICEINFO,
|
||||
ODK_MESSAGECOUNTER,
|
||||
ODK_RENEWALDATA,
|
||||
ODK_HASH,
|
||||
// The "stressable" types are the ones we can put in a stress test that packs
|
||||
@@ -71,10 +73,17 @@ struct ODK_ProvisioningResponseParams {
|
||||
ODK_CoreMessage core_message;
|
||||
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX];
|
||||
uint32_t device_id_length;
|
||||
uint32_t padding_u32;
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
ODK_ParsedProvisioning parsed_provisioning;
|
||||
std::vector<ODK_Field> extra_fields;
|
||||
};
|
||||
|
||||
struct ODK_Provisioning40ResponseParams {
|
||||
ODK_CoreMessage core_message;
|
||||
std::vector<ODK_Field> extra_fields;
|
||||
};
|
||||
|
||||
// Default values in core_message for testing
|
||||
void ODK_SetDefaultCoreFields(ODK_CoreMessage* core_message,
|
||||
ODK_MessageType message_type);
|
||||
@@ -82,7 +91,9 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params,
|
||||
uint32_t odk_major_version);
|
||||
void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params);
|
||||
void ODK_SetDefaultProvisioningResponseParams(
|
||||
ODK_ProvisioningResponseParams* params);
|
||||
ODK_ProvisioningResponseParams* params, uint32_t odk_major_version);
|
||||
void ODK_SetDefaultProvisioning40ResponseParams(
|
||||
ODK_Provisioning40ResponseParams* params);
|
||||
|
||||
size_t ODK_FieldLength(ODK_FieldType type);
|
||||
size_t ODK_AllocSize(ODK_FieldType type);
|
||||
@@ -92,8 +103,8 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field);
|
||||
// Load buf to ODK_Field
|
||||
OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf, const ODK_Field* field);
|
||||
OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf, const ODK_Field* field);
|
||||
OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf,
|
||||
const size_t size_in, size_t* size_out,
|
||||
OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf, size_t size_in,
|
||||
size_t* size_out,
|
||||
const std::vector<ODK_Field>& fields);
|
||||
void ODK_ExpectEqualBuf(const void* s1, const void* s2, size_t n,
|
||||
const std::vector<ODK_Field>& fields);
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "odk.h"
|
||||
#include "odk_structs.h"
|
||||
#include "odk_structs_priv.h"
|
||||
#include "odk_test_helper.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -23,6 +25,99 @@ constexpr uint64_t kRentalClockStart = 1000u;
|
||||
// renewal is not loaded.
|
||||
constexpr uint64_t kGracePeriod = 5u;
|
||||
|
||||
constexpr uint32_t kExtraPayloadSize = 128u;
|
||||
|
||||
constexpr uint32_t kSystemTime = 20u;
|
||||
|
||||
namespace wvodk_test {
|
||||
|
||||
TEST(OdkTimerBasicTest, ParseLicenseTimerSet) {
|
||||
// playback timer is successfully started
|
||||
::wvodk_test::ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION);
|
||||
params.parsed_license.renewal_delay_base = OEMCrypto_License_Load;
|
||||
params.parsed_license.timer_limits.soft_enforce_rental_duration = false;
|
||||
params.parsed_license.timer_limits.soft_enforce_playback_duration = false;
|
||||
params.parsed_license.timer_limits.earliest_playback_start_seconds = 10;
|
||||
params.parsed_license.timer_limits.total_playback_duration_seconds = 0;
|
||||
params.parsed_license.timer_limits.rental_duration_seconds = 10;
|
||||
params.parsed_license.timer_limits.initial_renewal_duration_seconds = 0;
|
||||
OEMCryptoResult result =
|
||||
ODK_InitializeClockValues(¶ms.clock_values, kSystemTime);
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, result);
|
||||
params.clock_values.time_of_license_request_signed = 5;
|
||||
params.clock_values.status = kActive;
|
||||
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
&buf_size);
|
||||
|
||||
result = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, kSystemTime, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(ODK_SET_TIMER, result);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
TEST(OdkTimerBasicTest, ParseLicenseTimerDisabled) {
|
||||
// playback timer is successfully started
|
||||
::wvodk_test::ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION);
|
||||
params.parsed_license.renewal_delay_base = OEMCrypto_License_Load;
|
||||
params.parsed_license.timer_limits.soft_enforce_rental_duration = true;
|
||||
params.parsed_license.timer_limits.earliest_playback_start_seconds = 3;
|
||||
params.parsed_license.timer_limits.total_playback_duration_seconds = 0;
|
||||
params.parsed_license.timer_limits.initial_renewal_duration_seconds = 0;
|
||||
params.clock_values.time_of_first_decrypt = 10;
|
||||
params.clock_values.time_of_license_request_signed = 5;
|
||||
params.clock_values.status = kActive;
|
||||
|
||||
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, kSystemTime, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(ODK_DISABLE_TIMER, result);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
TEST(OdkTimerBasicTest, ParseRenewalTimerExpired) {
|
||||
// playback timer is successfully started
|
||||
::wvodk_test::ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION);
|
||||
|
||||
params.parsed_license.renewal_delay_base = OEMCrypto_License_Load;
|
||||
params.parsed_license.timer_limits.rental_duration_seconds = 5;
|
||||
params.parsed_license.timer_limits.earliest_playback_start_seconds = 3;
|
||||
OEMCryptoResult result =
|
||||
ODK_InitializeClockValues(¶ms.clock_values, kSystemTime);
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, result);
|
||||
params.clock_values.time_of_license_request_signed = 5;
|
||||
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t buf_size = 0;
|
||||
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
|
||||
&buf_size);
|
||||
|
||||
result = ODK_ParseLicense(
|
||||
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
|
||||
params.usage_entry_present, kSystemTime, &(params.timer_limits),
|
||||
&(params.clock_values), &(params.core_message.nonce_values),
|
||||
&(params.parsed_license), nullptr);
|
||||
EXPECT_EQ(ODK_TIMER_EXPIRED, result);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
} // namespace wvodk_test
|
||||
|
||||
TEST(OdkTimerBasicTest, NullTest) {
|
||||
// Assert that nullptr does not cause a core dump.
|
||||
ODK_InitializeClockValues(nullptr, 0u);
|
||||
|
||||
Reference in New Issue
Block a user