Add import/export and version API
This commit is contained in:
@@ -19,6 +19,7 @@ cc_library(
|
|||||||
"ALWAYS_DECRYPT_TO_CLEAR",
|
"ALWAYS_DECRYPT_TO_CLEAR",
|
||||||
"HAS_GENERIC_CRYPTO",
|
"HAS_GENERIC_CRYPTO",
|
||||||
"HAS_SIGN_PST_REPORT",
|
"HAS_SIGN_PST_REPORT",
|
||||||
|
"HAS_IMPORT_EXPORT",
|
||||||
],
|
],
|
||||||
"//:is_old_api": [],
|
"//:is_old_api": [],
|
||||||
"//:is_old_vmpra": [],
|
"//:is_old_vmpra": [],
|
||||||
@@ -36,6 +37,15 @@ cc_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "enums",
|
||||||
|
hdrs = [
|
||||||
|
"enums.h",
|
||||||
|
],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [":shared_settings"],
|
||||||
|
)
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "result",
|
name = "result",
|
||||||
hdrs = [
|
hdrs = [
|
||||||
@@ -52,6 +62,7 @@ cc_library(
|
|||||||
],
|
],
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":enums",
|
||||||
":result",
|
":result",
|
||||||
":shared_settings",
|
":shared_settings",
|
||||||
],
|
],
|
||||||
@@ -61,9 +72,11 @@ cc_library(
|
|||||||
name = "license_whitebox",
|
name = "license_whitebox",
|
||||||
hdrs = [
|
hdrs = [
|
||||||
"license_whitebox.h",
|
"license_whitebox.h",
|
||||||
|
"license_whitebox_latest.h",
|
||||||
],
|
],
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":enums",
|
||||||
":result",
|
":result",
|
||||||
":shared_settings",
|
":shared_settings",
|
||||||
],
|
],
|
||||||
|
|||||||
61
whitebox/api/enums.h
Normal file
61
whitebox/api/enums.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// Copyright 2024 Google LLC. All Rights Reserved.
|
||||||
|
|
||||||
|
#ifndef WHITEBOX_API_ENUMS_H_
|
||||||
|
#define WHITEBOX_API_ENUMS_H_
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WB_CIPHER_MODE_CTR,
|
||||||
|
WB_CIPHER_MODE_CBC,
|
||||||
|
} WB_CipherMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WB_KEY_QUERY_TYPE_SIGNING_KEY,
|
||||||
|
WB_KEY_QUERY_TYPE_CONTENT_KEY,
|
||||||
|
WB_KEY_QUERY_TYPE_GENERIC_KEY,
|
||||||
|
} WB_KeyQueryType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WB_KCB_FLAGS_ALLOW_ENCRYPT = (1u << 8),
|
||||||
|
WB_KCB_FLAGS_ALLOW_DECRYPT = (1u << 7),
|
||||||
|
WB_KCB_FLAGS_ALLOW_SIGN = (1u << 6),
|
||||||
|
WB_KCB_FLAGS_ALLOW_VERIFY = (1u << 5),
|
||||||
|
|
||||||
|
WB_KCB_FLAGS_GENERIC_MASK = 0x1e0,
|
||||||
|
WB_KCB_FLAGS_SECURITY_LEVEL_SHIFT = 26,
|
||||||
|
WB_KCB_FLAGS_SECURITY_LEVEL_MASK = 0x3 << WB_KCB_FLAGS_SECURITY_LEVEL_SHIFT,
|
||||||
|
} WB_KcbFlags;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// The key was found in the license but there was something wrong it and could
|
||||||
|
// not be loaded.
|
||||||
|
WB_KEY_STATUS_INVALID,
|
||||||
|
|
||||||
|
// The key was found in the license and can be used with
|
||||||
|
// |WB_License_SignRenewalRequest()| and with
|
||||||
|
// |WB_License_VerifyRenewalResponse()|.
|
||||||
|
WB_KEY_STATUS_SIGNING_KEY_VALID,
|
||||||
|
|
||||||
|
// The key was found in the license. However, the permisions of the key are
|
||||||
|
// different depending on its status.
|
||||||
|
//
|
||||||
|
// | DECRYPT | MASKED DECRYPT |
|
||||||
|
// ---------------+---------+----------------+
|
||||||
|
// VALID | No | No |
|
||||||
|
// MASKED_DECRYPT | No | Yes |
|
||||||
|
// DECRYPT | Yes | Yes |
|
||||||
|
WB_KEY_STATUS_CONTENT_KEY_VALID,
|
||||||
|
WB_KEY_STATUS_CONTENT_KEY_MASKED_DECRYPT,
|
||||||
|
WB_KEY_STATUS_CONTENT_KEY_DECRYPT,
|
||||||
|
} WB_KeyStatus;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// The license response uses single key - the license signing and encryption
|
||||||
|
// key are the same.
|
||||||
|
WB_LICENSE_KEY_MODE_SINGLE_KEY,
|
||||||
|
|
||||||
|
// The license response uses two keys - the license signing and encryption
|
||||||
|
// key are different.
|
||||||
|
WB_LICENSE_KEY_MODE_DUAL_KEY,
|
||||||
|
} WB_LicenseKeyMode;
|
||||||
|
|
||||||
|
#endif // WHITEBOX_API_ENUMS_H_
|
||||||
@@ -1,74 +1,48 @@
|
|||||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||||
|
|
||||||
#ifndef WHITEBOX_API_LICENSE_WHITEBOX_H_
|
// #ifndef WHITEBOX_API_LICENSE_WHITEBOX_H_
|
||||||
#define WHITEBOX_API_LICENSE_WHITEBOX_H_
|
// Don't use header guards to allow including the same header with different
|
||||||
|
// versions. For example:
|
||||||
|
//
|
||||||
|
// #include "license_whitebox.h" // Adds WB_License_Create
|
||||||
|
// #define WB_VERSION 28
|
||||||
|
// #include "license_whitebox.h" // Adds WB_License_Create_v28
|
||||||
|
// #define WB_VERSION 29
|
||||||
|
// #include "license_whitebox.h" // Adds WB_License_Create_v29
|
||||||
|
//
|
||||||
|
// This file should only contain forward declarations. It cannot contain
|
||||||
|
// definitions like classes, enums, or typedefs.
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "api/enums.h"
|
||||||
#include "api/result.h"
|
#include "api/result.h"
|
||||||
|
|
||||||
|
// Define WB_VERSION to concat that version to the function names. If it isn't
|
||||||
|
// defined, we will define non-versioned function names.
|
||||||
|
// #define WB_VERSION 28
|
||||||
|
|
||||||
|
#ifdef WB_VERSION
|
||||||
|
// We do this triple-indirection here since the ## operator handles arguments
|
||||||
|
// a bit weird and we want to expand the WB_RESULT as a value, not an identifier
|
||||||
|
//
|
||||||
|
// WB_CONCAT_VERSION(Foo) -> Foo_v28
|
||||||
|
# define WB_CONCAT_VERSION__(a, b) a ## b
|
||||||
|
# define WB_CONCAT_VERSION_(name, version) \
|
||||||
|
WB_CONCAT_VERSION__(name ## _v, version)
|
||||||
|
# define WB_CONCAT_VERSION(name) WB_CONCAT_VERSION_(name, WB_VERSION)
|
||||||
|
#else
|
||||||
|
# define WB_CONCAT_VERSION(name) name
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The opaque type representing a single white-box instance.
|
// The opaque type representing a single white-box instance.
|
||||||
typedef struct WB_License_Whitebox WB_License_Whitebox;
|
typedef struct WB_CONCAT_VERSION(WB_License_Whitebox)
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox);
|
||||||
typedef enum {
|
|
||||||
WB_CIPHER_MODE_CTR,
|
|
||||||
WB_CIPHER_MODE_CBC,
|
|
||||||
} WB_CipherMode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
WB_KEY_QUERY_TYPE_SIGNING_KEY,
|
|
||||||
WB_KEY_QUERY_TYPE_CONTENT_KEY,
|
|
||||||
WB_KEY_QUERY_TYPE_GENERIC_KEY,
|
|
||||||
} WB_KeyQueryType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
WB_KCB_FLAGS_ALLOW_ENCRYPT = (1u << 8),
|
|
||||||
WB_KCB_FLAGS_ALLOW_DECRYPT = (1u << 7),
|
|
||||||
WB_KCB_FLAGS_ALLOW_SIGN = (1u << 6),
|
|
||||||
WB_KCB_FLAGS_ALLOW_VERIFY = (1u << 5),
|
|
||||||
|
|
||||||
WB_KCB_FLAGS_GENERIC_MASK = 0x1e0,
|
|
||||||
WB_KCB_FLAGS_SECURITY_LEVEL_SHIFT = 26,
|
|
||||||
WB_KCB_FLAGS_SECURITY_LEVEL_MASK = 0x3 << WB_KCB_FLAGS_SECURITY_LEVEL_SHIFT,
|
|
||||||
} WB_KcbFlags;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
// The key was found in the license but there was something wrong it and could
|
|
||||||
// not be loaded.
|
|
||||||
WB_KEY_STATUS_INVALID,
|
|
||||||
|
|
||||||
// The key was found in the license and can be used with
|
|
||||||
// |WB_License_SignRenewalRequest()| and with
|
|
||||||
// |WB_License_VerifyRenewalResponse()|.
|
|
||||||
WB_KEY_STATUS_SIGNING_KEY_VALID,
|
|
||||||
|
|
||||||
// The key was found in the license. However, the permisions of the key are
|
|
||||||
// different depending on its status.
|
|
||||||
//
|
|
||||||
// | DECRYPT | MASKED DECRYPT |
|
|
||||||
// ---------------+---------+----------------+
|
|
||||||
// VALID | No | No |
|
|
||||||
// MASKED_DECRYPT | No | Yes |
|
|
||||||
// DECRYPT | Yes | Yes |
|
|
||||||
WB_KEY_STATUS_CONTENT_KEY_VALID,
|
|
||||||
WB_KEY_STATUS_CONTENT_KEY_MASKED_DECRYPT,
|
|
||||||
WB_KEY_STATUS_CONTENT_KEY_DECRYPT,
|
|
||||||
} WB_KeyStatus;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
// The license response uses single key - the license signing and encryption
|
|
||||||
// key are the same.
|
|
||||||
WB_LICENSE_KEY_MODE_SINGLE_KEY,
|
|
||||||
|
|
||||||
// The license response uses two keys - the license signing and encryption
|
|
||||||
// key are different.
|
|
||||||
WB_LICENSE_KEY_MODE_DUAL_KEY,
|
|
||||||
} WB_LicenseKeyMode;
|
|
||||||
|
|
||||||
// Creates a new white-box instance using the implementation's internal private
|
// Creates a new white-box instance using the implementation's internal private
|
||||||
// key|. A pointer to the white-box instance will be returned via |whitebox|.
|
// key|. A pointer to the white-box instance will be returned via |whitebox|.
|
||||||
@@ -88,17 +62,74 @@ typedef enum {
|
|||||||
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null.
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null.
|
||||||
//
|
//
|
||||||
// WB_RESULT_OUT_OF_MEMORY if the necessary memory could not be allocated.
|
// WB_RESULT_OUT_OF_MEMORY if the necessary memory could not be allocated.
|
||||||
WB_Result WB_License_Create(const uint8_t* whitebox_init_data,
|
WB_Result WB_CONCAT_VERSION(WB_License_Create)(
|
||||||
|
const uint8_t* whitebox_init_data,
|
||||||
size_t whitebox_init_data_size,
|
size_t whitebox_init_data_size,
|
||||||
WB_License_Whitebox** whitebox);
|
WB_CONCAT_VERSION(WB_License_Whitebox)** whitebox);
|
||||||
|
|
||||||
|
// Creates a new white-box instance by loading the exported keys from the given
|
||||||
|
// buffer. A pointer to the white-box instance will be returned via |whitebox|.
|
||||||
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
|
// Args:
|
||||||
|
// buffer (in): The exported key buffer.
|
||||||
|
//
|
||||||
|
// buffer_size (in): The number of bytes in buffer.
|
||||||
|
//
|
||||||
|
// whitebox (out) : The output parameter used to return the new white-box
|
||||||
|
// instance.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// WB_RESULT_OK if the white-box instance was successfully created.
|
||||||
|
//
|
||||||
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null.
|
||||||
|
//
|
||||||
|
// WB_RESULT_OUT_OF_MEMORY if the necessary memory could not be allocated.
|
||||||
|
WB_Result WB_CONCAT_VERSION(WB_License_Import)(
|
||||||
|
const uint8_t* buffer,
|
||||||
|
size_t buffer_size,
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)** whitebox);
|
||||||
|
|
||||||
// Releases all resources used by the white-box instance pointed to by
|
// Releases all resources used by the white-box instance pointed to by
|
||||||
// |whitebox|.
|
// |whitebox|.
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : A pointer to a white-box instance. Passing in null will
|
// whitebox (in) : A pointer to a white-box instance. Passing in null will
|
||||||
// result in a no-op.
|
// result in a no-op.
|
||||||
void WB_License_Delete(WB_License_Whitebox* whitebox);
|
void WB_CONCAT_VERSION(WB_License_Delete)(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox);
|
||||||
|
|
||||||
|
// Exports the client MAC key, content keys, and generic keys in a persistent
|
||||||
|
// format. This format will be stored on disk as-is; it should be encrypted or
|
||||||
|
// otherwise protected against reading or usage.
|
||||||
|
//
|
||||||
|
// Args:
|
||||||
|
// whitebox (in) : The white-box containing the keys to export
|
||||||
|
// |input_data|.
|
||||||
|
//
|
||||||
|
// buffer(out) : The output buffer to write the data to.
|
||||||
|
//
|
||||||
|
// buffer_size(in/out) : On input, contains the maximum number of bytes in
|
||||||
|
// |buffer|. On output should contain the number of bytes used by the
|
||||||
|
// data.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// WB_RESULT_OK if the key was successfully exported.
|
||||||
|
//
|
||||||
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |buffer| was null,
|
||||||
|
// if |buffer_size| was null.
|
||||||
|
//
|
||||||
|
// WB_RESULT_BUFFER_TOO_SMALL if |buffer_size| (as input) was less than the
|
||||||
|
// required size.
|
||||||
|
//
|
||||||
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
||||||
|
WB_Result WB_CONCAT_VERSION(WB_License_ExportKeys)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
uint8_t* buffer,
|
||||||
|
size_t* buffer_size);
|
||||||
|
|
||||||
// Initializes tables and data needed for the WB_License_SignLicenseRequest()
|
// Initializes tables and data needed for the WB_License_SignLicenseRequest()
|
||||||
// function.
|
// function.
|
||||||
@@ -112,7 +143,7 @@ void WB_License_Delete(WB_License_Whitebox* whitebox);
|
|||||||
// Returns:
|
// Returns:
|
||||||
// WB_RESULT_OK if the initialization succeeded.
|
// WB_RESULT_OK if the initialization succeeded.
|
||||||
// WB_RESULT_INVALID_STATE otherwise.
|
// WB_RESULT_INVALID_STATE otherwise.
|
||||||
WB_Result WB_License_SignLicenseRequest_Init();
|
WB_Result WB_CONCAT_VERSION(WB_License_SignLicenseRequest_Init)();
|
||||||
|
|
||||||
// Signs a license request using the CDM's private signing key.
|
// Signs a license request using the CDM's private signing key.
|
||||||
//
|
//
|
||||||
@@ -143,7 +174,8 @@ WB_Result WB_License_SignLicenseRequest_Init();
|
|||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if WB_License_SignLicenseRequest_Init() has not been
|
// WB_RESULT_INVALID_STATE if WB_License_SignLicenseRequest_Init() has not been
|
||||||
// called and completed.
|
// called and completed.
|
||||||
WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_SignLicenseRequest)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* license_request,
|
const uint8_t* license_request,
|
||||||
size_t license_request_size,
|
size_t license_request_size,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
@@ -162,7 +194,7 @@ WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox,
|
|||||||
// Returns:
|
// Returns:
|
||||||
// WB_RESULT_OK if the initialization succeeded.
|
// WB_RESULT_OK if the initialization succeeded.
|
||||||
// WB_RESULT_INVALID_STATE otherwise.
|
// WB_RESULT_INVALID_STATE otherwise.
|
||||||
WB_Result WB_License_ProcessLicenseResponse_Init();
|
WB_Result WB_CONCAT_VERSION(WB_License_ProcessLicenseResponse_Init)();
|
||||||
|
|
||||||
// Verifies a license response using HMAC and the server signing key.
|
// Verifies a license response using HMAC and the server signing key.
|
||||||
//
|
//
|
||||||
@@ -239,7 +271,8 @@ WB_Result WB_License_ProcessLicenseResponse_Init();
|
|||||||
// the behaviour is undefined. The two preferrable results are:
|
// the behaviour is undefined. The two preferrable results are:
|
||||||
// 1. The key is considered value and is loaded.
|
// 1. The key is considered value and is loaded.
|
||||||
// 2. The key is considered invalid and is not loaded.
|
// 2. The key is considered invalid and is not loaded.
|
||||||
WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_ProcessLicenseResponse)(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
WB_LicenseKeyMode license_key_mode,
|
WB_LicenseKeyMode license_key_mode,
|
||||||
const uint8_t* core_message,
|
const uint8_t* core_message,
|
||||||
size_t core_message_size,
|
size_t core_message_size,
|
||||||
@@ -287,7 +320,8 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
|||||||
// license.
|
// license.
|
||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
||||||
WB_Result WB_License_LoadEntitledContentKey(WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_LoadEntitledContentKey)(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* entitlement_key_id,
|
const uint8_t* entitlement_key_id,
|
||||||
size_t entitlement_key_id_size,
|
size_t entitlement_key_id_size,
|
||||||
const uint8_t* content_key_id,
|
const uint8_t* content_key_id,
|
||||||
@@ -314,13 +348,16 @@ WB_Result WB_License_LoadEntitledContentKey(WB_License_Whitebox* whitebox,
|
|||||||
// WB_RESULT_KEY_UNAVAILABLE if the requested key was not added.
|
// WB_RESULT_KEY_UNAVAILABLE if the requested key was not added.
|
||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
||||||
WB_Result WB_License_RemoveEntitledContentKey(WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_RemoveEntitledContentKey)(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* content_key_id,
|
const uint8_t* content_key_id,
|
||||||
size_t content_key_id_size);
|
size_t content_key_id_size);
|
||||||
|
|
||||||
// Queries the white-box to know whether or not the white-box loaded a specific
|
// Queries the white-box to know whether or not the white-box loaded a specific
|
||||||
// key and to know what operations can be performed with that key.
|
// key and to know what operations can be performed with that key.
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : An initialized white-box instance.
|
// whitebox (in) : An initialized white-box instance.
|
||||||
//
|
//
|
||||||
@@ -353,7 +390,8 @@ WB_Result WB_License_RemoveEntitledContentKey(WB_License_Whitebox* whitebox,
|
|||||||
// Since the white-box can skip invalid/malformed content keys,
|
// Since the white-box can skip invalid/malformed content keys,
|
||||||
// WB_License_QueryKeyState() provides a means to know which keys we
|
// WB_License_QueryKeyState() provides a means to know which keys we
|
||||||
// successfully loaded.
|
// successfully loaded.
|
||||||
WB_Result WB_License_QueryKeyStatus(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_QueryKeyStatus)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
WB_KeyQueryType type,
|
WB_KeyQueryType type,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
@@ -362,6 +400,8 @@ WB_Result WB_License_QueryKeyStatus(const WB_License_Whitebox* whitebox,
|
|||||||
// Signs |message| and return the signature via |signature| using HMAC-SHA256
|
// Signs |message| and return the signature via |signature| using HMAC-SHA256
|
||||||
// and the client renewal signing key
|
// and the client renewal signing key
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : The white-box instance containing the signing key.
|
// whitebox (in) : The white-box instance containing the signing key.
|
||||||
//
|
//
|
||||||
@@ -388,7 +428,8 @@ WB_Result WB_License_QueryKeyStatus(const WB_License_Whitebox* whitebox,
|
|||||||
// required size.
|
// required size.
|
||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if |whitebox| had no signing keys.
|
// WB_RESULT_INVALID_STATE if |whitebox| had no signing keys.
|
||||||
WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_SignRenewalRequest)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
size_t message_size,
|
size_t message_size,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
@@ -397,6 +438,8 @@ WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox,
|
|||||||
// Signs |message| and return the signature via |signature| using HMAC-SHA1 and
|
// Signs |message| and return the signature via |signature| using HMAC-SHA1 and
|
||||||
// the client renewal signing key
|
// the client renewal signing key
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : The white-box instance containing the signing key.
|
// whitebox (in) : The white-box instance containing the signing key.
|
||||||
//
|
//
|
||||||
@@ -423,7 +466,8 @@ WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox,
|
|||||||
// required size.
|
// required size.
|
||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if |whitebox| had no signing keys.
|
// WB_RESULT_INVALID_STATE if |whitebox| had no signing keys.
|
||||||
WB_Result WB_License_SignPstReport(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_SignPstReport)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
size_t message_size,
|
size_t message_size,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
@@ -453,7 +497,8 @@ WB_Result WB_License_SignPstReport(const WB_License_Whitebox* whitebox,
|
|||||||
// |signature|.
|
// |signature|.
|
||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
||||||
WB_Result WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_VerifyRenewalResponse)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
size_t message_size,
|
size_t message_size,
|
||||||
const uint8_t* signature,
|
const uint8_t* signature,
|
||||||
@@ -503,7 +548,8 @@ WB_Result WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox,
|
|||||||
// the required size.
|
// the required size.
|
||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
||||||
WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GetSecretString)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
WB_CipherMode mode,
|
WB_CipherMode mode,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
@@ -516,6 +562,8 @@ WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
|
|||||||
// This must support |input_data| and |output_data| pointing to the same buffer
|
// This must support |input_data| and |output_data| pointing to the same buffer
|
||||||
// (in-place operation).
|
// (in-place operation).
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : The white-box containing the keys needed to decrypt
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
||||||
// |input_data|.
|
// |input_data|.
|
||||||
@@ -560,7 +608,8 @@ WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
|
|||||||
//
|
//
|
||||||
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
||||||
// permission bit sets in the KCB to allow encrypt.
|
// permission bit sets in the KCB to allow encrypt.
|
||||||
WB_Result WB_License_GenericEncrypt(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GenericEncrypt)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
const uint8_t* input_data,
|
const uint8_t* input_data,
|
||||||
@@ -576,6 +625,8 @@ WB_Result WB_License_GenericEncrypt(const WB_License_Whitebox* whitebox,
|
|||||||
// This must support |input_data| and |output_data| pointing to the same buffer
|
// This must support |input_data| and |output_data| pointing to the same buffer
|
||||||
// (in-place operation).
|
// (in-place operation).
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : The white-box containing the keys needed to decrypt
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
||||||
// |input_data|.
|
// |input_data|.
|
||||||
@@ -620,7 +671,8 @@ WB_Result WB_License_GenericEncrypt(const WB_License_Whitebox* whitebox,
|
|||||||
//
|
//
|
||||||
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
||||||
// permission bit sets in the KCB to allow decrypt.
|
// permission bit sets in the KCB to allow decrypt.
|
||||||
WB_Result WB_License_GenericDecrypt(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GenericDecrypt)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
const uint8_t* input_data,
|
const uint8_t* input_data,
|
||||||
@@ -633,6 +685,8 @@ WB_Result WB_License_GenericDecrypt(const WB_License_Whitebox* whitebox,
|
|||||||
// Performs a generic crypto "sign" operation that takes the given message in
|
// Performs a generic crypto "sign" operation that takes the given message in
|
||||||
// |input_data| and places the signature in |output_data|.
|
// |input_data| and places the signature in |output_data|.
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : The white-box containing the keys needed to decrypt
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
||||||
// |input_data|.
|
// |input_data|.
|
||||||
@@ -672,7 +726,8 @@ WB_Result WB_License_GenericDecrypt(const WB_License_Whitebox* whitebox,
|
|||||||
//
|
//
|
||||||
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
||||||
// permission bit sets in the KCB to allow sign.
|
// permission bit sets in the KCB to allow sign.
|
||||||
WB_Result WB_License_GenericSign(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GenericSign)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
@@ -683,6 +738,8 @@ WB_Result WB_License_GenericSign(const WB_License_Whitebox* whitebox,
|
|||||||
// Performs a generic crypto "verify" operation that takes |message| and
|
// Performs a generic crypto "verify" operation that takes |message| and
|
||||||
// verifies the signature matches |signature|.
|
// verifies the signature matches |signature|.
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : The white-box containing the keys needed to decrypt
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
||||||
// |input_data|.
|
// |input_data|.
|
||||||
@@ -718,7 +775,8 @@ WB_Result WB_License_GenericSign(const WB_License_Whitebox* whitebox,
|
|||||||
//
|
//
|
||||||
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
||||||
// permission bit sets in the KCB to allow verify.
|
// permission bit sets in the KCB to allow verify.
|
||||||
WB_Result WB_License_GenericVerify(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GenericVerify)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
@@ -731,6 +789,8 @@ WB_Result WB_License_GenericVerify(const WB_License_Whitebox* whitebox,
|
|||||||
// This must support |input_data| and |output_data| pointing to the same buffer
|
// This must support |input_data| and |output_data| pointing to the same buffer
|
||||||
// (in-place decrypt).
|
// (in-place decrypt).
|
||||||
//
|
//
|
||||||
|
// This function can be used in the limited offline builds.
|
||||||
|
//
|
||||||
// Args:
|
// Args:
|
||||||
// whitebox (in) : The white-box containing the keys needed to decrypt
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
||||||
// |input_data|.
|
// |input_data|.
|
||||||
@@ -777,7 +837,8 @@ WB_Result WB_License_GenericVerify(const WB_License_Whitebox* whitebox,
|
|||||||
// the required size.
|
// the required size.
|
||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
||||||
WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_Decrypt)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
WB_CipherMode mode,
|
WB_CipherMode mode,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
@@ -844,7 +905,8 @@ WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox,
|
|||||||
// than the required size.
|
// than the required size.
|
||||||
//
|
//
|
||||||
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
||||||
WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_MaskedDecrypt)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
WB_CipherMode mode,
|
WB_CipherMode mode,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
@@ -881,7 +943,8 @@ WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox,
|
|||||||
// secret_string_size (in) : The number of bytes in |secret_string|.
|
// secret_string_size (in) : The number of bytes in |secret_string|.
|
||||||
//
|
//
|
||||||
// unmasked_data (out) : The output buffer to write the unmasked data to.
|
// unmasked_data (out) : The output buffer to write the unmasked data to.
|
||||||
void WB_License_Unmask(const uint8_t* masked_data,
|
void WB_CONCAT_VERSION(WB_License_Unmask)(
|
||||||
|
const uint8_t* masked_data,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
size_t size,
|
size_t size,
|
||||||
const uint8_t* secret_string,
|
const uint8_t* secret_string,
|
||||||
@@ -892,4 +955,3 @@ void WB_License_Unmask(const uint8_t* masked_data,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // WHITEBOX_API_LICENSE_WHITEBOX_H_
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||||
|
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox_latest.h"
|
||||||
|
|
||||||
#include "api/license_whitebox_provider_keys_test_data.h"
|
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox_latest.h"
|
||||||
#include "api/license_whitebox_benchmark.h"
|
#include "api/license_whitebox_benchmark.h"
|
||||||
#include "api/license_whitebox_provider_keys_test_data.h"
|
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||||
#include "api/result.h"
|
#include "api/result.h"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const size_t kInvalidProviderKeyId = 0xfff;
|
|||||||
|
|
||||||
class LicenseWhiteboxDecryptTest
|
class LicenseWhiteboxDecryptTest
|
||||||
: public LicenseWhiteboxTestBase,
|
: public LicenseWhiteboxTestBase,
|
||||||
public ::testing::WithParamInterface<std::tuple<Padding, size_t>> {
|
public ::testing::WithParamInterface<std::tuple<Padding, size_t, bool>> {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
LicenseWhiteboxTestBase::SetUp();
|
LicenseWhiteboxTestBase::SetUp();
|
||||||
@@ -69,7 +69,7 @@ class LicenseWhiteboxDecryptTest
|
|||||||
License license;
|
License license;
|
||||||
builder.Build(*server, &license);
|
builder.Build(*server, &license);
|
||||||
|
|
||||||
const auto result = WB_License_ProcessLicenseResponse(
|
auto result = WB_License_ProcessLicenseResponse(
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license.core_message.data(),
|
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license.core_message.data(),
|
||||||
license.core_message.size(), license.message.data(),
|
license.core_message.size(), license.message.data(),
|
||||||
license.message.size(), license.signature.data(),
|
license.message.size(), license.signature.data(),
|
||||||
@@ -83,6 +83,11 @@ class LicenseWhiteboxDecryptTest
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EXPECT_EQ(result, WB_RESULT_OK);
|
EXPECT_EQ(result, WB_RESULT_OK);
|
||||||
|
|
||||||
|
if (std::get<2>(GetParam())) {
|
||||||
|
RecreateOffline();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,7 +648,8 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
::testing::Values(kNoProviderKeyId,
|
::testing::Values(kNoProviderKeyId,
|
||||||
kValidProviderKeyId1,
|
kValidProviderKeyId1,
|
||||||
kValidProviderKeyId2,
|
kValidProviderKeyId2,
|
||||||
kInvalidProviderKeyId)));
|
kInvalidProviderKeyId),
|
||||||
|
::testing::Values(false)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
PKSC8,
|
PKSC8,
|
||||||
@@ -652,5 +658,14 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
::testing::Values(kNoProviderKeyId,
|
::testing::Values(kNoProviderKeyId,
|
||||||
kValidProviderKeyId1,
|
kValidProviderKeyId1,
|
||||||
kValidProviderKeyId2,
|
kValidProviderKeyId2,
|
||||||
kInvalidProviderKeyId)));
|
kInvalidProviderKeyId),
|
||||||
|
::testing::Values(false)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
Offline,
|
||||||
|
LicenseWhiteboxDecryptTest,
|
||||||
|
::testing::Combine(::testing::Values(Padding::kNone, Padding::kPKSC8),
|
||||||
|
::testing::Values(kNoProviderKeyId),
|
||||||
|
::testing::Values(true)));
|
||||||
|
|
||||||
} // namespace widevine
|
} // namespace widevine
|
||||||
|
|||||||
@@ -3,9 +3,11 @@
|
|||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/golden_data.h"
|
#include "api/golden_data.h"
|
||||||
|
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||||
#include "api/license_whitebox_test_base.h"
|
#include "api/license_whitebox_test_base.h"
|
||||||
#include "api/test_license_builder.h"
|
#include "api/test_license_builder.h"
|
||||||
#include "testing/gmock/include/gmock/gmock-matchers.h"
|
#include "testing/gmock/include/gmock/gmock-matchers.h"
|
||||||
@@ -88,7 +90,7 @@ INSTANTIATE_TEST_SUITE_P(All,
|
|||||||
|
|
||||||
class LicenseWhiteboxGenericCryptoTest
|
class LicenseWhiteboxGenericCryptoTest
|
||||||
: public LicenseWhiteboxTestBase,
|
: public LicenseWhiteboxTestBase,
|
||||||
public testing::WithParamInterface<bool> {
|
public testing::WithParamInterface<std::tuple<bool, bool>> {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() {
|
void SetUp() {
|
||||||
LicenseWhiteboxTestBase::SetUp();
|
LicenseWhiteboxTestBase::SetUp();
|
||||||
@@ -97,7 +99,7 @@ class LicenseWhiteboxGenericCryptoTest
|
|||||||
TestLicenseBuilder builder;
|
TestLicenseBuilder builder;
|
||||||
builder.GetSettings().odk_version = TestLicenseBuilder::OdkVersion::k16_5;
|
builder.GetSettings().odk_version = TestLicenseBuilder::OdkVersion::k16_5;
|
||||||
builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey());
|
builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey());
|
||||||
if (GetParam()) {
|
if (std::get<0>(GetParam())) {
|
||||||
builder.AddGenericKey(golden_data_.GenericContent().encrypt_decrypt_key);
|
builder.AddGenericKey(golden_data_.GenericContent().encrypt_decrypt_key);
|
||||||
builder.AddGenericKey(golden_data_.GenericContent().sign_verify_key);
|
builder.AddGenericKey(golden_data_.GenericContent().sign_verify_key);
|
||||||
} else {
|
} else {
|
||||||
@@ -107,13 +109,7 @@ class LicenseWhiteboxGenericCryptoTest
|
|||||||
builder.AddGenericKey(golden_data_.GenericContent().verify_key);
|
builder.AddGenericKey(golden_data_.GenericContent().verify_key);
|
||||||
}
|
}
|
||||||
builder.Build(*server_, &license_);
|
builder.Build(*server_, &license_);
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<TestServer> server_;
|
|
||||||
License license_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, NoContentDecrypt) {
|
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
auto result = WB_License_ProcessLicenseResponse(
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
||||||
license_.core_message.size(), license_.message.data(),
|
license_.core_message.size(), license_.message.data(),
|
||||||
@@ -125,16 +121,26 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, NoContentDecrypt) {
|
|||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
#else
|
#else
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
ASSERT_EQ(result, WB_RESULT_OK);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
if (std::get<1>(GetParam())) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RecreateOffline());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<TestServer> server_;
|
||||||
|
License license_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(LicenseWhiteboxGenericCryptoTest, NoContentDecrypt) {
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.decrypt_key.id;
|
: content.decrypt_key.id;
|
||||||
std::vector<uint8_t> actual(content.plaintext.size());
|
std::vector<uint8_t> actual(content.plaintext.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR, key_id.data(),
|
auto result = WB_License_Decrypt(
|
||||||
key_id.size(), content.encrypted.data(),
|
whitebox_, WB_CIPHER_MODE_CTR, key_id.data(), key_id.size(),
|
||||||
content.encrypted.size(), content.iv.data(),
|
content.encrypted.data(), content.encrypted.size(), content.iv.data(),
|
||||||
content.iv.size(), actual.data(), &actual_size);
|
content.iv.size(), actual.data(), &actual_size);
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
#ifndef HAS_GENERIC_CRYPTO
|
||||||
ASSERT_EQ(result, WB_RESULT_INVALID_STATE);
|
ASSERT_EQ(result, WB_RESULT_INVALID_STATE);
|
||||||
@@ -144,6 +150,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, NoContentDecrypt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, NoGenericWithContent) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, NoGenericWithContent) {
|
||||||
|
// Recreate whitebox since the SetUp already loaded a license.
|
||||||
|
WB_License_Delete(whitebox_);
|
||||||
|
const auto init_data = GetLicenseWhiteboxProviderKeysInitData();
|
||||||
|
ASSERT_EQ(WB_License_Create(init_data.data(), init_data.size(), &whitebox_),
|
||||||
|
WB_RESULT_OK);
|
||||||
|
|
||||||
auto& content = golden_data_.CTRContent();
|
auto& content = golden_data_.CTRContent();
|
||||||
auto& key = content.software_crypto_key;
|
auto& key = content.software_crypto_key;
|
||||||
TestLicenseBuilder builder;
|
TestLicenseBuilder builder;
|
||||||
@@ -162,6 +174,10 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, NoGenericWithContent) {
|
|||||||
// Content key, expecting success regardless of HAS_GENERIC_CRYPTO support.
|
// Content key, expecting success regardless of HAS_GENERIC_CRYPTO support.
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
ASSERT_EQ(result, WB_RESULT_OK);
|
||||||
|
|
||||||
|
if (std::get<1>(GetParam())) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RecreateOffline());
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> actual(content.plaintext.size());
|
std::vector<uint8_t> actual(content.plaintext.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericDecrypt(
|
result = WB_License_GenericDecrypt(
|
||||||
@@ -176,25 +192,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, NoGenericWithContent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, Decrypt) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, Decrypt) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.decrypt_key.id;
|
: content.decrypt_key.id;
|
||||||
std::vector<uint8_t> actual(content.plaintext.size());
|
std::vector<uint8_t> actual(content.plaintext.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericDecrypt(
|
auto result = WB_License_GenericDecrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
||||||
content.encrypted.size(), content.iv.data(), content.iv.size(),
|
content.encrypted.size(), content.iv.data(), content.iv.size(),
|
||||||
actual.data(), &actual_size);
|
actual.data(), &actual_size);
|
||||||
@@ -210,24 +213,11 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, Decrypt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptShortBuffer) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptShortBuffer) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.decrypt_key.id;
|
: content.decrypt_key.id;
|
||||||
size_t actual_size = 0;
|
size_t actual_size = 0;
|
||||||
result = WB_License_GenericDecrypt(
|
auto result = WB_License_GenericDecrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
||||||
content.encrypted.size(), content.iv.data(), content.iv.size(), nullptr,
|
content.encrypted.size(), content.iv.data(), content.iv.size(), nullptr,
|
||||||
&actual_size);
|
&actual_size);
|
||||||
@@ -240,25 +230,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptShortBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptMissingKey) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptMissingKey) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = !std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
!GetParam() ? content.encrypt_decrypt_key.id : content.decrypt_key.id;
|
: content.decrypt_key.id;
|
||||||
std::vector<uint8_t> actual(content.plaintext.size());
|
std::vector<uint8_t> actual(content.plaintext.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericDecrypt(
|
auto result = WB_License_GenericDecrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
||||||
content.encrypted.size(), content.iv.data(), content.iv.size(),
|
content.encrypted.size(), content.iv.data(), content.iv.size(),
|
||||||
actual.data(), &actual_size);
|
actual.data(), &actual_size);
|
||||||
@@ -270,24 +247,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptMissingKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptKeyUsage) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptKeyUsage) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id = GetParam() ? content.sign_verify_key.id : content.sign_key.id;
|
auto& key_id = std::get<0>(GetParam()) ? content.sign_verify_key.id
|
||||||
|
: content.sign_key.id;
|
||||||
std::vector<uint8_t> actual(content.plaintext.size());
|
std::vector<uint8_t> actual(content.plaintext.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericDecrypt(
|
auto result = WB_License_GenericDecrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
||||||
content.encrypted.size(), content.iv.data(), content.iv.size(),
|
content.encrypted.size(), content.iv.data(), content.iv.size(),
|
||||||
actual.data(), &actual_size);
|
actual.data(), &actual_size);
|
||||||
@@ -299,26 +264,13 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptKeyUsage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptDataSize) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptDataSize) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.decrypt_key.id;
|
: content.decrypt_key.id;
|
||||||
std::vector<uint8_t> actual(content.plaintext.size());
|
std::vector<uint8_t> actual(content.plaintext.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
// Input size should be a multiple of 16
|
// Input size should be a multiple of 16
|
||||||
result = WB_License_GenericDecrypt(
|
auto result = WB_License_GenericDecrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
whitebox_, key_id.data(), key_id.size(), content.encrypted.data(),
|
||||||
content.encrypted.size() - 5, content.iv.data(), content.iv.size(),
|
content.encrypted.size() - 5, content.iv.data(), content.iv.size(),
|
||||||
actual.data(), &actual_size);
|
actual.data(), &actual_size);
|
||||||
@@ -330,25 +282,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, DecryptDataSize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, Encrypt) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, Encrypt) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.encrypt_key.id;
|
: content.encrypt_key.id;
|
||||||
std::vector<uint8_t> actual(content.encrypted.size());
|
std::vector<uint8_t> actual(content.encrypted.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericEncrypt(
|
auto result = WB_License_GenericEncrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), content.iv.data(), content.iv.size(),
|
content.plaintext.size(), content.iv.data(), content.iv.size(),
|
||||||
actual.data(), &actual_size);
|
actual.data(), &actual_size);
|
||||||
@@ -364,24 +303,11 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, Encrypt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptShortBuffer) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptShortBuffer) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.encrypt_key.id;
|
: content.encrypt_key.id;
|
||||||
size_t actual_size = 0;
|
size_t actual_size = 0;
|
||||||
result = WB_License_GenericEncrypt(
|
auto result = WB_License_GenericEncrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), content.iv.data(), content.iv.size(), nullptr,
|
content.plaintext.size(), content.iv.data(), content.iv.size(), nullptr,
|
||||||
&actual_size);
|
&actual_size);
|
||||||
@@ -394,25 +320,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptShortBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptMissingKey) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptMissingKey) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = !std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
!GetParam() ? content.encrypt_decrypt_key.id : content.encrypt_key.id;
|
: content.encrypt_key.id;
|
||||||
std::vector<uint8_t> actual(content.encrypted.size());
|
std::vector<uint8_t> actual(content.encrypted.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericEncrypt(
|
auto result = WB_License_GenericEncrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), content.iv.data(), content.iv.size(),
|
content.plaintext.size(), content.iv.data(), content.iv.size(),
|
||||||
actual.data(), &actual_size);
|
actual.data(), &actual_size);
|
||||||
@@ -424,24 +337,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptMissingKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptKeyUsage) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptKeyUsage) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id = GetParam() ? content.sign_verify_key.id : content.sign_key.id;
|
auto& key_id = std::get<0>(GetParam()) ? content.sign_verify_key.id
|
||||||
|
: content.sign_key.id;
|
||||||
std::vector<uint8_t> actual(content.encrypted.size());
|
std::vector<uint8_t> actual(content.encrypted.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericEncrypt(
|
auto result = WB_License_GenericEncrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), content.iv.data(), content.iv.size(),
|
content.plaintext.size(), content.iv.data(), content.iv.size(),
|
||||||
actual.data(), &actual_size);
|
actual.data(), &actual_size);
|
||||||
@@ -453,26 +354,13 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptKeyUsage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptDataSize) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptDataSize) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.encrypt_key.id;
|
: content.encrypt_key.id;
|
||||||
std::vector<uint8_t> actual(content.encrypted.size());
|
std::vector<uint8_t> actual(content.encrypted.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
// Input size should be a multiple of 16
|
// Input size should be a multiple of 16
|
||||||
result = WB_License_GenericEncrypt(
|
auto result = WB_License_GenericEncrypt(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size() - 5, content.iv.data(), content.iv.size(),
|
content.plaintext.size() - 5, content.iv.data(), content.iv.size(),
|
||||||
actual.data(), &actual_size);
|
actual.data(), &actual_size);
|
||||||
@@ -484,24 +372,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, EncryptDataSize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, Sign) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, Sign) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id = GetParam() ? content.sign_verify_key.id : content.sign_key.id;
|
auto& key_id = std::get<0>(GetParam()) ? content.sign_verify_key.id
|
||||||
|
: content.sign_key.id;
|
||||||
std::vector<uint8_t> actual(content.signature.size());
|
std::vector<uint8_t> actual(content.signature.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericSign(
|
auto result = WB_License_GenericSign(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), actual.data(), &actual_size);
|
content.plaintext.size(), actual.data(), &actual_size);
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
#ifndef HAS_GENERIC_CRYPTO
|
||||||
@@ -516,23 +392,11 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, Sign) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, SignShortBuffer) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, SignShortBuffer) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id = GetParam() ? content.sign_verify_key.id : content.sign_key.id;
|
auto& key_id = std::get<0>(GetParam()) ? content.sign_verify_key.id
|
||||||
|
: content.sign_key.id;
|
||||||
size_t actual_size = 0;
|
size_t actual_size = 0;
|
||||||
result = WB_License_GenericSign(
|
auto result = WB_License_GenericSign(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), nullptr, &actual_size);
|
content.plaintext.size(), nullptr, &actual_size);
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
#ifndef HAS_GENERIC_CRYPTO
|
||||||
@@ -544,24 +408,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, SignShortBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, SignMissingKey) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, SignMissingKey) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id = !GetParam() ? content.sign_verify_key.id : content.sign_key.id;
|
auto& key_id = !std::get<0>(GetParam()) ? content.sign_verify_key.id
|
||||||
|
: content.sign_key.id;
|
||||||
std::vector<uint8_t> actual(content.signature.size());
|
std::vector<uint8_t> actual(content.signature.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericSign(
|
auto result = WB_License_GenericSign(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), actual.data(), &actual_size);
|
content.plaintext.size(), actual.data(), &actual_size);
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
#ifndef HAS_GENERIC_CRYPTO
|
||||||
@@ -572,25 +424,12 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, SignMissingKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, SignKeyUsage) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, SignKeyUsage) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.decrypt_key.id;
|
: content.decrypt_key.id;
|
||||||
std::vector<uint8_t> actual(content.signature.size());
|
std::vector<uint8_t> actual(content.signature.size());
|
||||||
size_t actual_size = actual.size();
|
size_t actual_size = actual.size();
|
||||||
result = WB_License_GenericSign(
|
auto result = WB_License_GenericSign(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), actual.data(), &actual_size);
|
content.plaintext.size(), actual.data(), &actual_size);
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
#ifndef HAS_GENERIC_CRYPTO
|
||||||
@@ -601,26 +440,13 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, SignKeyUsage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, Verify) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, Verify) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.sign_verify_key.id
|
||||||
GetParam() ? content.sign_verify_key.id : content.verify_key.id;
|
: content.verify_key.id;
|
||||||
auto temp_signature = content.signature;
|
auto temp_signature = content.signature;
|
||||||
// Test once successfully, then make the signature invalid and test again.
|
// Test once successfully, then make the signature invalid and test again.
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
result = WB_License_GenericVerify(
|
auto result = WB_License_GenericVerify(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), temp_signature.data(), temp_signature.size());
|
content.plaintext.size(), temp_signature.data(), temp_signature.size());
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
#ifndef HAS_GENERIC_CRYPTO
|
||||||
@@ -633,24 +459,11 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, Verify) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, VerifyMissingKey) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, VerifyMissingKey) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = !std::get<0>(GetParam()) ? content.sign_verify_key.id
|
||||||
!GetParam() ? content.sign_verify_key.id : content.verify_key.id;
|
: content.verify_key.id;
|
||||||
auto temp_signature = content.signature;
|
auto temp_signature = content.signature;
|
||||||
result = WB_License_GenericVerify(
|
auto result = WB_License_GenericVerify(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), temp_signature.data(), temp_signature.size());
|
content.plaintext.size(), temp_signature.data(), temp_signature.size());
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
#ifndef HAS_GENERIC_CRYPTO
|
||||||
@@ -661,24 +474,11 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, VerifyMissingKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(LicenseWhiteboxGenericCryptoTest, VerifyKeyUsage) {
|
TEST_P(LicenseWhiteboxGenericCryptoTest, VerifyKeyUsage) {
|
||||||
auto result = WB_License_ProcessLicenseResponse(
|
|
||||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
|
||||||
license_.core_message.size(), license_.message.data(),
|
|
||||||
license_.message.size(), license_.signature.data(),
|
|
||||||
license_.signature.size(), license_.session_key.data(),
|
|
||||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
|
||||||
license_.request.size());
|
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
|
||||||
#else
|
|
||||||
ASSERT_EQ(result, WB_RESULT_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& content = golden_data_.GenericContent();
|
auto& content = golden_data_.GenericContent();
|
||||||
auto& key_id =
|
auto& key_id = std::get<0>(GetParam()) ? content.encrypt_decrypt_key.id
|
||||||
GetParam() ? content.encrypt_decrypt_key.id : content.decrypt_key.id;
|
: content.decrypt_key.id;
|
||||||
auto temp_signature = content.signature;
|
auto temp_signature = content.signature;
|
||||||
result = WB_License_GenericVerify(
|
auto result = WB_License_GenericVerify(
|
||||||
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
whitebox_, key_id.data(), key_id.size(), content.plaintext.data(),
|
||||||
content.plaintext.size(), temp_signature.data(), temp_signature.size());
|
content.plaintext.size(), temp_signature.data(), temp_signature.size());
|
||||||
#ifndef HAS_GENERIC_CRYPTO
|
#ifndef HAS_GENERIC_CRYPTO
|
||||||
@@ -690,6 +490,7 @@ TEST_P(LicenseWhiteboxGenericCryptoTest, VerifyKeyUsage) {
|
|||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(All,
|
INSTANTIATE_TEST_SUITE_P(All,
|
||||||
LicenseWhiteboxGenericCryptoTest,
|
LicenseWhiteboxGenericCryptoTest,
|
||||||
testing::Bool());
|
::testing::Combine(::testing::Bool(),
|
||||||
|
::testing::Bool()));
|
||||||
|
|
||||||
} // namespace widevine
|
} // namespace widevine
|
||||||
|
|||||||
262
whitebox/api/license_whitebox_latest.h
Normal file
262
whitebox/api/license_whitebox_latest.h
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
// Copyright 2024 Google LLC. All Rights Reserved.
|
||||||
|
|
||||||
|
#ifndef WHITEBOX_API_LICENSE_WHITEBOX_LATEST_H_
|
||||||
|
#define WHITEBOX_API_LICENSE_WHITEBOX_LATEST_H_
|
||||||
|
|
||||||
|
#include "api/license_whitebox.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WB_VERSION
|
||||||
|
|
||||||
|
typedef WB_CONCAT_VERSION(WB_License_Whitebox) WB_License_Whitebox;
|
||||||
|
|
||||||
|
inline WB_Result WB_License_Create(
|
||||||
|
const uint8_t* whitebox_init_data,
|
||||||
|
size_t whitebox_init_data_size,
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)** whitebox) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_Create)(
|
||||||
|
whitebox_init_data, whitebox_init_data_size, whitebox);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_Import(
|
||||||
|
const uint8_t* buffer,
|
||||||
|
size_t buffer_size,
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)** whitebox) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_Import)(buffer, buffer_size, whitebox);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WB_License_Delete(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_Delete)(whitebox);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_ExportKeys(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
uint8_t* buffer,
|
||||||
|
size_t* buffer_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_ExportKeys)(whitebox, buffer,
|
||||||
|
buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_SignLicenseRequest_Init() {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_SignLicenseRequest_Init)();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_SignLicenseRequest(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* license_request,
|
||||||
|
size_t license_request_size,
|
||||||
|
uint8_t* signature,
|
||||||
|
size_t* signature_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_SignLicenseRequest)(
|
||||||
|
whitebox, license_request, license_request_size, signature,
|
||||||
|
signature_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_ProcessLicenseResponse_Init() {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_ProcessLicenseResponse_Init)();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_ProcessLicenseResponse(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
WB_LicenseKeyMode license_key_mode,
|
||||||
|
const uint8_t* core_message,
|
||||||
|
size_t core_message_size,
|
||||||
|
const uint8_t* message,
|
||||||
|
size_t message_size,
|
||||||
|
const uint8_t* signature,
|
||||||
|
size_t signature_size,
|
||||||
|
const uint8_t* session_key,
|
||||||
|
size_t session_key_size,
|
||||||
|
size_t provider_key_id,
|
||||||
|
const uint8_t* license_request,
|
||||||
|
size_t license_request_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_ProcessLicenseResponse)(
|
||||||
|
whitebox, license_key_mode, core_message, core_message_size, message,
|
||||||
|
message_size, signature, signature_size, session_key, session_key_size,
|
||||||
|
provider_key_id, license_request, license_request_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_LoadEntitledContentKey(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* entitlement_key_id,
|
||||||
|
size_t entitlement_key_id_size,
|
||||||
|
const uint8_t* content_key_id,
|
||||||
|
size_t content_key_id_size,
|
||||||
|
const uint8_t* iv,
|
||||||
|
size_t iv_size,
|
||||||
|
const uint8_t* key_data,
|
||||||
|
size_t key_data_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_LoadEntitledContentKey)(
|
||||||
|
whitebox, entitlement_key_id, entitlement_key_id_size, content_key_id,
|
||||||
|
content_key_id_size, iv, iv_size, key_data, key_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_RemoveEntitledContentKey(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* content_key_id,
|
||||||
|
size_t content_key_id_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_RemoveEntitledContentKey)(
|
||||||
|
whitebox, content_key_id, content_key_id_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_QueryKeyStatus(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
WB_KeyQueryType type,
|
||||||
|
const uint8_t* key_id,
|
||||||
|
size_t key_id_size,
|
||||||
|
WB_KeyStatus* key_status) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_QueryKeyStatus)(whitebox, type, key_id,
|
||||||
|
key_id_size, key_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_SignRenewalRequest(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* message,
|
||||||
|
size_t message_size,
|
||||||
|
uint8_t* signature,
|
||||||
|
size_t* signature_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_SignRenewalRequest)(
|
||||||
|
whitebox, message, message_size, signature, signature_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_SignPstReport(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* message,
|
||||||
|
size_t message_size,
|
||||||
|
uint8_t* signature,
|
||||||
|
size_t* signature_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_SignPstReport)(
|
||||||
|
whitebox, message, message_size, signature, signature_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_VerifyRenewalResponse(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* message,
|
||||||
|
size_t message_size,
|
||||||
|
const uint8_t* signature,
|
||||||
|
size_t signature_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_VerifyRenewalResponse)(
|
||||||
|
whitebox, message, message_size, signature, signature_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_GetSecretString(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
WB_CipherMode mode,
|
||||||
|
const uint8_t* key_id,
|
||||||
|
size_t key_id_size,
|
||||||
|
uint8_t* secret_string,
|
||||||
|
size_t* secret_string_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_GetSecretString)(
|
||||||
|
whitebox, mode, key_id, key_id_size, secret_string, secret_string_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_GenericEncrypt(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* key_id,
|
||||||
|
size_t key_id_size,
|
||||||
|
const uint8_t* input_data,
|
||||||
|
size_t input_data_size,
|
||||||
|
const uint8_t* iv,
|
||||||
|
size_t iv_size,
|
||||||
|
uint8_t* output_data,
|
||||||
|
size_t* output_data_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_GenericEncrypt)(
|
||||||
|
whitebox, key_id, key_id_size, input_data, input_data_size, iv, iv_size,
|
||||||
|
output_data, output_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_GenericDecrypt(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* key_id,
|
||||||
|
size_t key_id_size,
|
||||||
|
const uint8_t* input_data,
|
||||||
|
size_t input_data_size,
|
||||||
|
const uint8_t* iv,
|
||||||
|
size_t iv_size,
|
||||||
|
uint8_t* output_data,
|
||||||
|
size_t* output_data_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_GenericDecrypt)(
|
||||||
|
whitebox, key_id, key_id_size, input_data, input_data_size, iv, iv_size,
|
||||||
|
output_data, output_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_GenericSign(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* key_id,
|
||||||
|
size_t key_id_size,
|
||||||
|
const uint8_t* message,
|
||||||
|
size_t message_size,
|
||||||
|
uint8_t* output_data,
|
||||||
|
size_t* output_data_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_GenericSign)(
|
||||||
|
whitebox, key_id, key_id_size, message, message_size, output_data,
|
||||||
|
output_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_GenericVerify(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
const uint8_t* key_id,
|
||||||
|
size_t key_id_size,
|
||||||
|
const uint8_t* message,
|
||||||
|
size_t message_size,
|
||||||
|
const uint8_t* signature,
|
||||||
|
size_t signature_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_GenericVerify)(
|
||||||
|
whitebox, key_id, key_id_size, message, message_size, signature,
|
||||||
|
signature_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_Decrypt(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
WB_CipherMode mode,
|
||||||
|
const uint8_t* key_id,
|
||||||
|
size_t key_id_size,
|
||||||
|
const uint8_t* input_data,
|
||||||
|
size_t input_data_size,
|
||||||
|
const uint8_t* iv,
|
||||||
|
size_t iv_size,
|
||||||
|
uint8_t* output_data,
|
||||||
|
size_t* output_data_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_Decrypt)(
|
||||||
|
whitebox, mode, key_id, key_id_size, input_data, input_data_size, iv,
|
||||||
|
iv_size, output_data, output_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline WB_Result WB_License_MaskedDecrypt(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
WB_CipherMode mode,
|
||||||
|
const uint8_t* key_id,
|
||||||
|
size_t key_id_size,
|
||||||
|
const uint8_t* input_data,
|
||||||
|
size_t input_data_size,
|
||||||
|
const uint8_t* iv,
|
||||||
|
size_t iv_size,
|
||||||
|
uint8_t* masked_output_data,
|
||||||
|
size_t* masked_output_data_size) {
|
||||||
|
return WB_CONCAT_VERSION(WB_License_MaskedDecrypt)(
|
||||||
|
whitebox, mode, key_id, key_id_size, input_data, input_data_size, iv,
|
||||||
|
iv_size, masked_output_data, masked_output_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WB_License_Unmask(const uint8_t* masked_data,
|
||||||
|
size_t offset,
|
||||||
|
size_t size,
|
||||||
|
const uint8_t* secret_string,
|
||||||
|
size_t secret_string_size,
|
||||||
|
uint8_t* unmasked_data) {
|
||||||
|
WB_CONCAT_VERSION(WB_License_Unmask)(masked_data, offset, size, secret_string,
|
||||||
|
secret_string_size, unmasked_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined(WB_VERSION)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // WHITEBOX_API_LICENSE_WHITEBOX_LATEST_H_
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/golden_data.h"
|
#include "api/golden_data.h"
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox_latest.h"
|
||||||
#include "api/license_whitebox_provider_keys_test_data.h"
|
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||||
#include "api/test_license_builder.h"
|
#include "api/test_license_builder.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox_latest.h"
|
||||||
#include "api/license_whitebox_benchmark.h"
|
#include "api/license_whitebox_benchmark.h"
|
||||||
#include "api/license_whitebox_provider_keys_test_data.h"
|
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||||
#include "api/result.h"
|
#include "api/result.h"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox_latest.h"
|
||||||
#include "api/license_whitebox_benchmark.h"
|
#include "api/license_whitebox_benchmark.h"
|
||||||
#include "api/license_whitebox_provider_keys_test_data.h"
|
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||||
#include "api/result.h"
|
#include "api/result.h"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/license_whitebox_test_base.h"
|
#include "api/license_whitebox_test_base.h"
|
||||||
@@ -18,7 +19,7 @@ constexpr const bool kRenewal = true;
|
|||||||
|
|
||||||
class LicenseWhiteboxSignRenewalPstTest
|
class LicenseWhiteboxSignRenewalPstTest
|
||||||
: public LicenseWhiteboxTestBase,
|
: public LicenseWhiteboxTestBase,
|
||||||
public testing::WithParamInterface<bool> {
|
public testing::WithParamInterface<std::tuple<bool, bool>> {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
LicenseWhiteboxTestBase::SetUp();
|
LicenseWhiteboxTestBase::SetUp();
|
||||||
@@ -28,7 +29,8 @@ class LicenseWhiteboxSignRenewalPstTest
|
|||||||
signature_size_ = 256;
|
signature_size_ = 256;
|
||||||
signature_.resize(signature_size_);
|
signature_.resize(signature_size_);
|
||||||
|
|
||||||
sign_func_ = GetParam() == kRenewal ? &WB_License_SignRenewalRequest
|
sign_func_ = std::get<0>(GetParam()) == kRenewal
|
||||||
|
? &WB_License_SignRenewalRequest
|
||||||
: &WB_License_SignPstReport;
|
: &WB_License_SignPstReport;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +59,10 @@ class LicenseWhiteboxSignRenewalPstTest
|
|||||||
license.session_key.data(), license.session_key.size(),
|
license.session_key.data(), license.session_key.size(),
|
||||||
kNoProviderKeyId, license.request.data(), license.request.size()),
|
kNoProviderKeyId, license.request.data(), license.request.size()),
|
||||||
WB_RESULT_OK);
|
WB_RESULT_OK);
|
||||||
|
|
||||||
|
if (std::get<1>(GetParam())) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RecreateOffline());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the expected signature for |message|. By returning the message, this
|
// Get the expected signature for |message|. By returning the message, this
|
||||||
@@ -67,7 +73,7 @@ class LicenseWhiteboxSignRenewalPstTest
|
|||||||
std::string key_str(signing_key_.begin(), signing_key_.end());
|
std::string key_str(signing_key_.begin(), signing_key_.end());
|
||||||
key_str.erase(0, crypto_util::kSigningKeySizeBytes);
|
key_str.erase(0, crypto_util::kSigningKeySizeBytes);
|
||||||
|
|
||||||
auto func = GetParam() == kRenewal
|
auto func = std::get<0>(GetParam()) == kRenewal
|
||||||
? &widevine::crypto_util::CreateSignatureHmacSha256
|
? &widevine::crypto_util::CreateSignatureHmacSha256
|
||||||
: &widevine::crypto_util::CreateSignatureHmacSha1;
|
: &widevine::crypto_util::CreateSignatureHmacSha1;
|
||||||
const std::string signature =
|
const std::string signature =
|
||||||
@@ -100,13 +106,13 @@ class LicenseWhiteboxSignRenewalPstTest
|
|||||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, SuccessWithInvalidRequest) {
|
TEST_P(LicenseWhiteboxSignRenewalPstTest, SuccessWithInvalidRequest) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
const auto result =
|
const auto result =
|
||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -120,13 +126,13 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, SuccessWithInvalidRequest) {
|
|||||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, SuccessWithSigningKeyPKSC8Padding) {
|
TEST_P(LicenseWhiteboxSignRenewalPstTest, SuccessWithSigningKeyPKSC8Padding) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kPKSC8;
|
settings.padding = TestLicenseBuilder::Padding::kPKSC8;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
const auto result =
|
const auto result =
|
||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -140,13 +146,13 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, SuccessWithSigningKeyPKSC8Padding) {
|
|||||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullWhitebox) {
|
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullWhitebox) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
const auto result =
|
const auto result =
|
||||||
sign_func_(nullptr, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(nullptr, garbage_request_.data(), garbage_request_.size(),
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -157,12 +163,12 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullWhitebox) {
|
|||||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullMessage) {
|
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullMessage) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
const auto result = sign_func_(whitebox_, nullptr, garbage_request_.size(),
|
const auto result = sign_func_(whitebox_, nullptr, garbage_request_.size(),
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -173,12 +179,12 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullMessage) {
|
|||||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForZeroMessageSize) {
|
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForZeroMessageSize) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
const auto result = sign_func_(whitebox_, garbage_request_.data(), 0,
|
const auto result = sign_func_(whitebox_, garbage_request_.data(), 0,
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -189,14 +195,14 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForZeroMessageSize) {
|
|||||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, CanProbeSizeWithNullSignature) {
|
TEST_P(LicenseWhiteboxSignRenewalPstTest, CanProbeSizeWithNullSignature) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
signature_size_ = 0;
|
signature_size_ = 0;
|
||||||
|
|
||||||
const auto result =
|
const auto result =
|
||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
nullptr, &signature_size_);
|
nullptr, &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -208,13 +214,13 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, CanProbeSizeWithNullSignature) {
|
|||||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullSignature) {
|
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullSignature) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
const auto result =
|
const auto result =
|
||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
nullptr, &signature_size_);
|
nullptr, &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -226,13 +232,13 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest,
|
|||||||
InvalidParameterForNullSignatureSize) {
|
InvalidParameterForNullSignatureSize) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
const auto result =
|
const auto result =
|
||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
signature_.data(), nullptr);
|
signature_.data(), nullptr);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -243,7 +249,7 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest,
|
|||||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, BufferTooSmall) {
|
TEST_P(LicenseWhiteboxSignRenewalPstTest, BufferTooSmall) {
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
// We need the signature to be too small. While it would be possible to use
|
// We need the signature to be too small. While it would be possible to use
|
||||||
// zero, using a non-zero value ensures that we are not combining "empty" and
|
// zero, using a non-zero value ensures that we are not combining "empty" and
|
||||||
@@ -254,7 +260,7 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, BufferTooSmall) {
|
|||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -276,7 +282,7 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidStateForNoLicense) {
|
|||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -311,7 +317,7 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, KeyUnavailableForNoSigningKey) {
|
|||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -325,13 +331,13 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, KeyUnavailableForInvalidKey) {
|
|||||||
// just need an invalid key, so we use one way of invalidating the key.
|
// just need an invalid key, so we use one way of invalidating the key.
|
||||||
TestLicenseBuilder::Settings settings;
|
TestLicenseBuilder::Settings settings;
|
||||||
settings.include_signing_key_iv = false;
|
settings.include_signing_key_iv = false;
|
||||||
LoadLicense(settings);
|
ASSERT_NO_FATAL_FAILURE(LoadLicense(settings));
|
||||||
|
|
||||||
const auto result =
|
const auto result =
|
||||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||||
signature_.data(), &signature_size_);
|
signature_.data(), &signature_size_);
|
||||||
#ifndef HAS_SIGN_PST_REPORT
|
#ifndef HAS_SIGN_PST_REPORT
|
||||||
if (GetParam() != kRenewal) {
|
if (std::get<0>(GetParam()) != kRenewal) {
|
||||||
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
GTEST_SKIP();
|
GTEST_SKIP();
|
||||||
}
|
}
|
||||||
@@ -339,11 +345,18 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, KeyUnavailableForInvalidKey) {
|
|||||||
ASSERT_EQ(result, WB_RESULT_KEY_UNAVAILABLE);
|
ASSERT_EQ(result, WB_RESULT_KEY_UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(TestAll,
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
TestAll,
|
||||||
LicenseWhiteboxSignRenewalPstTest,
|
LicenseWhiteboxSignRenewalPstTest,
|
||||||
testing::Bool(),
|
testing::Combine(testing::Bool(), testing::Bool()),
|
||||||
[](const testing::TestParamInfo<bool>& info) {
|
[](const testing::TestParamInfo<std::tuple<bool, bool>>& info) {
|
||||||
return info.param == kRenewal ? "Renewal" : "PST";
|
if (std::get<1>(info.param)) {
|
||||||
|
return std::get<0>(info.param) == kRenewal ? "Offline_Renewal"
|
||||||
|
: "Offline_PST";
|
||||||
|
} else {
|
||||||
|
return std::get<0>(info.param) == kRenewal ? "Streaming_Renewal"
|
||||||
|
: "Streaming_PST";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} // namespace widevine
|
} // namespace widevine
|
||||||
|
|||||||
@@ -19,6 +19,26 @@ void LicenseWhiteboxTestBase::TearDown() {
|
|||||||
WB_License_Delete(whitebox_);
|
WB_License_Delete(whitebox_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LicenseWhiteboxTestBase::RecreateOffline() {
|
||||||
|
std::vector<uint8_t> buffer;
|
||||||
|
size_t buffer_size = 0;
|
||||||
|
auto result = WB_License_ExportKeys(whitebox_, buffer.data(), &buffer_size);
|
||||||
|
#ifdef HAS_IMPORT_EXPORT
|
||||||
|
ASSERT_EQ(result, WB_RESULT_BUFFER_TOO_SMALL);
|
||||||
|
|
||||||
|
buffer.resize(buffer_size);
|
||||||
|
result = WB_License_ExportKeys(whitebox_, buffer.data(), &buffer_size);
|
||||||
|
ASSERT_EQ(result, WB_RESULT_OK);
|
||||||
|
|
||||||
|
WB_License_Delete(whitebox_);
|
||||||
|
result = WB_License_Import(buffer.data(), buffer_size, &whitebox_);
|
||||||
|
ASSERT_EQ(result, WB_RESULT_OK);
|
||||||
|
#else
|
||||||
|
ASSERT_EQ(result, WB_RESULT_NOT_IMPLEMENTED);
|
||||||
|
GTEST_SKIP();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void LicenseWhiteboxTestBase::Modify(std::vector<uint8_t>* data) const {
|
void LicenseWhiteboxTestBase::Modify(std::vector<uint8_t>* data) const {
|
||||||
ASSERT_TRUE(data);
|
ASSERT_TRUE(data);
|
||||||
ASSERT_GT(data->size(), 0u);
|
ASSERT_GT(data->size(), 0u);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "api/golden_data.h"
|
#include "api/golden_data.h"
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox_latest.h"
|
||||||
#include "crypto_utils/rsa_key.h"
|
#include "crypto_utils/rsa_key.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
@@ -18,6 +18,9 @@ class LicenseWhiteboxTestBase : public ::testing::Test {
|
|||||||
|
|
||||||
void TearDown() override;
|
void TearDown() override;
|
||||||
|
|
||||||
|
// Recreates the whitebox instance by exporting and importing the offline data
|
||||||
|
void RecreateOffline();
|
||||||
|
|
||||||
// Modify a buffer so that it won't be the exact same as it was before. This
|
// Modify a buffer so that it won't be the exact same as it was before. This
|
||||||
// to make it easier to invalidate signatures.
|
// to make it easier to invalidate signatures.
|
||||||
void Modify(std::vector<uint8_t>* data) const;
|
void Modify(std::vector<uint8_t>* data) const;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox.h"
|
||||||
|
#include "api/license_whitebox_latest.h"
|
||||||
#include "api/license_whitebox_provider_keys_test_data.h"
|
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox_latest.h"
|
||||||
#include "api/license_whitebox_benchmark.h"
|
#include "api/license_whitebox_benchmark.h"
|
||||||
#include "api/license_whitebox_provider_keys_test_data.h"
|
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||||
#include "api/result.h"
|
#include "api/result.h"
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ cc_library(
|
|||||||
srcs = ["odk.cc"],
|
srcs = ["odk.cc"],
|
||||||
hdrs = ["odk.h"],
|
hdrs = ["odk.h"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//api:enums",
|
||||||
"//api:result",
|
"//api:result",
|
||||||
"//api:shared_settings",
|
"//api:shared_settings",
|
||||||
"//chromium_deps/base:glog",
|
"//chromium_deps/base:glog",
|
||||||
@@ -67,6 +68,7 @@ cc_library(
|
|||||||
":content_key",
|
":content_key",
|
||||||
":odk",
|
":odk",
|
||||||
":renewal_key",
|
":renewal_key",
|
||||||
|
"//api:enums",
|
||||||
"//api:result",
|
"//api:result",
|
||||||
"//api:shared_settings",
|
"//api:shared_settings",
|
||||||
"//api:trap_keys",
|
"//api:trap_keys",
|
||||||
@@ -144,6 +146,7 @@ cc_library(
|
|||||||
":memory_util",
|
":memory_util",
|
||||||
"//api:aead_test_data",
|
"//api:aead_test_data",
|
||||||
"//api:aead_whitebox",
|
"//api:aead_whitebox",
|
||||||
|
"//api:enums",
|
||||||
"//api:result",
|
"//api:result",
|
||||||
"//api:shared_settings",
|
"//api:shared_settings",
|
||||||
"//chromium_deps/third_party/boringssl",
|
"//chromium_deps/third_party/boringssl",
|
||||||
@@ -170,6 +173,7 @@ cc_library(
|
|||||||
":private_keys",
|
":private_keys",
|
||||||
":protobuf_license_parser",
|
":protobuf_license_parser",
|
||||||
"//api:license_whitebox",
|
"//api:license_whitebox",
|
||||||
|
"//api:enums",
|
||||||
"//api:result",
|
"//api:result",
|
||||||
"//api:shared_settings",
|
"//api:shared_settings",
|
||||||
"//api:trap_keys",
|
"//api:trap_keys",
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "api/license_whitebox.h"
|
#include "api/license_whitebox.h"
|
||||||
#include "license_protocol.pb.h"
|
#include "license_protocol.pb.h"
|
||||||
|
|||||||
@@ -84,7 +84,10 @@ bool LicenseParser::UnwrapKey(
|
|||||||
// |provider_key_id| is used, so decrypt the unwrapped key using the
|
// |provider_key_id| is used, so decrypt the unwrapped key using the
|
||||||
// appropriate provider key.
|
// appropriate provider key.
|
||||||
std::string final_key;
|
std::string final_key;
|
||||||
const auto& provider_key = provider_keys[provider_key_id - 1].key;
|
const std::string provider_key{
|
||||||
|
provider_keys[provider_key_id - 1].key.begin(),
|
||||||
|
provider_keys[provider_key_id - 1].key.end()
|
||||||
|
};
|
||||||
const std::string no_iv(16, 0);
|
const std::string no_iv(16, 0);
|
||||||
if (!Decrypt(provider_key, no_iv, intermediate_key, &final_key)) {
|
if (!Decrypt(provider_key, no_iv, intermediate_key, &final_key)) {
|
||||||
DVLOG(1) << "Failed to decrypt content key using Provider Key.";
|
DVLOG(1) << "Failed to decrypt content key using Provider Key.";
|
||||||
|
|||||||
@@ -3,9 +3,11 @@
|
|||||||
#ifndef WHITEBOX_REFERENCE_IMPL_LICENSE_PARSER_H_
|
#ifndef WHITEBOX_REFERENCE_IMPL_LICENSE_PARSER_H_
|
||||||
#define WHITEBOX_REFERENCE_IMPL_LICENSE_PARSER_H_
|
#define WHITEBOX_REFERENCE_IMPL_LICENSE_PARSER_H_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "license_protocol.pb.h"
|
#include "license_protocol.pb.h"
|
||||||
#include "reference/impl/content_key.h"
|
#include "reference/impl/content_key.h"
|
||||||
#include "reference/impl/odk.h"
|
#include "reference/impl/odk.h"
|
||||||
@@ -16,8 +18,8 @@ namespace widevine {
|
|||||||
class LicenseParser {
|
class LicenseParser {
|
||||||
public:
|
public:
|
||||||
struct ProviderKey {
|
struct ProviderKey {
|
||||||
std::vector<uint8_t> mask;
|
std::array<uint8_t, 16> mask;
|
||||||
std::string key;
|
std::array<uint8_t, 16> key;
|
||||||
};
|
};
|
||||||
|
|
||||||
LicenseParser() = default;
|
LicenseParser() = default;
|
||||||
|
|||||||
@@ -110,10 +110,26 @@ std::string MakeString(const uint8_t* data, size_t size) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct WB_License_ExportedData_Key {
|
||||||
|
std::array<uint8_t, 16> key_id;
|
||||||
|
uint8_t key_id_size;
|
||||||
|
widevine::InternalKey key;
|
||||||
|
};
|
||||||
|
struct WB_License_ExportedData {
|
||||||
|
uint8_t version;
|
||||||
|
bool has_renewal;
|
||||||
|
std::array<uint8_t, 32> renewal_client;
|
||||||
|
size_t num_content_keys;
|
||||||
|
size_t num_generic_keys;
|
||||||
|
WB_License_ExportedData_Key keys[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr const uint8_t kExportedVersion = 1;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// The white-box type can't be in the namespace as it is declared in the header.
|
// The white-box type can't be in the namespace as it is declared in the header.
|
||||||
struct WB_License_Whitebox {
|
struct WB_CONCAT_VERSION(WB_License_Whitebox) {
|
||||||
// A basic flag to track whether or not we have loaded a license. We do this
|
// A basic flag to track whether or not we have loaded a license. We do this
|
||||||
// to avoid relying on signing keys and content keys to know if we loaded a
|
// to avoid relying on signing keys and content keys to know if we loaded a
|
||||||
// license.
|
// license.
|
||||||
@@ -163,7 +179,8 @@ std::vector<uint8_t> GetSecretStringFor(WB_CipherMode mode) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const widevine::InternalKey* FindKey(const WB_License_Whitebox* whitebox,
|
const widevine::InternalKey* FindKey(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* id,
|
const uint8_t* id,
|
||||||
size_t id_size) {
|
size_t id_size) {
|
||||||
CHECK(whitebox);
|
CHECK(whitebox);
|
||||||
@@ -319,8 +336,8 @@ std::vector<widevine::LicenseParser::ProviderKey> CreateProviderKeys(
|
|||||||
#ifdef HAS_PROVIDER_KEYS
|
#ifdef HAS_PROVIDER_KEYS
|
||||||
for (size_t i = 0; i < whitebox_init_data_size / 32; ++i) {
|
for (size_t i = 0; i < whitebox_init_data_size / 32; ++i) {
|
||||||
widevine::LicenseParser::ProviderKey provider_key;
|
widevine::LicenseParser::ProviderKey provider_key;
|
||||||
provider_key.mask.assign(whitebox_init_data, whitebox_init_data + 16);
|
memcpy(provider_key.mask.data(), whitebox_init_data, 16);
|
||||||
provider_key.key.assign(whitebox_init_data + 16, whitebox_init_data + 32);
|
memcpy(provider_key.key.data(), whitebox_init_data + 16, 16);
|
||||||
result.emplace_back(provider_key);
|
result.emplace_back(provider_key);
|
||||||
whitebox_init_data += 32;
|
whitebox_init_data += 32;
|
||||||
}
|
}
|
||||||
@@ -330,9 +347,10 @@ std::vector<widevine::LicenseParser::ProviderKey> CreateProviderKeys(
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
WB_Result WB_License_Create(const uint8_t* whitebox_init_data,
|
WB_Result WB_CONCAT_VERSION(WB_License_Create)(
|
||||||
|
const uint8_t* whitebox_init_data,
|
||||||
size_t whitebox_init_data_size,
|
size_t whitebox_init_data_size,
|
||||||
WB_License_Whitebox** whitebox) {
|
WB_CONCAT_VERSION(WB_License_Whitebox) * *whitebox) {
|
||||||
if (whitebox == nullptr) {
|
if (whitebox == nullptr) {
|
||||||
DVLOG(1) << "Invalid parameter: null pointer.";
|
DVLOG(1) << "Invalid parameter: null pointer.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
@@ -359,7 +377,7 @@ WB_Result WB_License_Create(const uint8_t* whitebox_init_data,
|
|||||||
|
|
||||||
// Should always be non-null on modern compilers
|
// Should always be non-null on modern compilers
|
||||||
// (https://isocpp.org/wiki/faq/freestore-mgmt).
|
// (https://isocpp.org/wiki/faq/freestore-mgmt).
|
||||||
*whitebox = new WB_License_Whitebox();
|
*whitebox = new WB_CONCAT_VERSION(WB_License_Whitebox)();
|
||||||
(*whitebox)->signing_key.swap(signing_key);
|
(*whitebox)->signing_key.swap(signing_key);
|
||||||
(*whitebox)->encryption_key.swap(encryption_key);
|
(*whitebox)->encryption_key.swap(encryption_key);
|
||||||
(*whitebox)->provider_keys =
|
(*whitebox)->provider_keys =
|
||||||
@@ -368,17 +386,131 @@ WB_Result WB_License_Create(const uint8_t* whitebox_init_data,
|
|||||||
return WB_RESULT_OK;
|
return WB_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WB_License_Delete(WB_License_Whitebox* whitebox) {
|
WB_Result WB_CONCAT_VERSION(WB_License_Import)(
|
||||||
|
const uint8_t* buffer,
|
||||||
|
size_t buffer_size,
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox)** whitebox) {
|
||||||
|
#ifdef HAS_IMPORT_EXPORT
|
||||||
|
if (whitebox == nullptr) {
|
||||||
|
DVLOG(1) << "Invalid parameter: null pointer.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
if (buffer_size == 0 || buffer == nullptr) {
|
||||||
|
DVLOG(1) << "Invalid parameter: Missing whitebox_init_data.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
if (buffer_size < sizeof(WB_License_ExportedData)) {
|
||||||
|
DVLOG(1) << "Invalid parameter: Buffer too small.";
|
||||||
|
return WB_RESULT_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* info = reinterpret_cast<const WB_License_ExportedData*>(buffer);
|
||||||
|
if (info->version != kExportedVersion) {
|
||||||
|
DVLOG(1) << "Unsupported version of exported data.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
if (buffer_size < sizeof(WB_License_ExportedData) +
|
||||||
|
(sizeof(WB_License_ExportedData_Key) *
|
||||||
|
(info->num_content_keys + info->num_generic_keys))) {
|
||||||
|
DVLOG(1) << "Invalid parameter: Buffer too small.";
|
||||||
|
return WB_RESULT_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*whitebox = new WB_CONCAT_VERSION(WB_License_Whitebox)();
|
||||||
|
(*whitebox)->initialized = true;
|
||||||
|
|
||||||
|
if (info->has_renewal) {
|
||||||
|
std::unique_ptr<widevine::RenewalKey> renewal_key{new widevine::RenewalKey};
|
||||||
|
renewal_key->status = WB_KEY_STATUS_SIGNING_KEY_VALID;
|
||||||
|
renewal_key->client = info->renewal_client;
|
||||||
|
(*whitebox)->renewal_key = std::move(renewal_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < info->num_content_keys; i++) {
|
||||||
|
auto& key = info->keys[i];
|
||||||
|
CHECK(key.key_id_size <= sizeof(key.key_id));
|
||||||
|
|
||||||
|
std::string key_id{key.key_id.begin(),
|
||||||
|
key.key_id.begin() + key.key_id_size};
|
||||||
|
(*whitebox)->content_keys.emplace(key_id, key.key);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < info->num_generic_keys; i++) {
|
||||||
|
const auto& key = info->keys[info->num_content_keys + i];
|
||||||
|
CHECK(key.key_id_size <= sizeof(key.key_id));
|
||||||
|
|
||||||
|
std::string key_id{key.key_id.data(), key.key_id.data() + key.key_id_size};
|
||||||
|
(*whitebox)->generic_keys.emplace(key_id, key.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WB_RESULT_OK;
|
||||||
|
#else
|
||||||
|
return WB_RESULT_NOT_IMPLEMENTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void WB_CONCAT_VERSION(WB_License_Delete)(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox) {
|
||||||
// Safe to delete nullptr (https://isocpp.org/wiki/faq/freestore-mgmt).
|
// Safe to delete nullptr (https://isocpp.org/wiki/faq/freestore-mgmt).
|
||||||
delete whitebox;
|
delete whitebox;
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_SignLicenseRequest_Init() {
|
WB_Result WB_CONCAT_VERSION(WB_License_ExportKeys)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox)* whitebox,
|
||||||
|
uint8_t* buffer,
|
||||||
|
size_t* buffer_size) {
|
||||||
|
#ifdef HAS_IMPORT_EXPORT
|
||||||
|
if (!whitebox || !buffer_size) {
|
||||||
|
DVLOG(1) << "Invalid parameter: null pointer.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
if (!whitebox->initialized) {
|
||||||
|
DVLOG(1) << "Invalid state: no license loaded.";
|
||||||
|
return WB_RESULT_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t required_size =
|
||||||
|
sizeof(WB_License_ExportedData) +
|
||||||
|
sizeof(WB_License_ExportedData_Key) *
|
||||||
|
(whitebox->content_keys.size() + whitebox->generic_keys.size());
|
||||||
|
if (!CheckAndUpdateSize(required_size, buffer_size) || !buffer) {
|
||||||
|
return WB_RESULT_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* info = reinterpret_cast<WB_License_ExportedData*>(buffer);
|
||||||
|
info->has_renewal =
|
||||||
|
whitebox->renewal_key &&
|
||||||
|
whitebox->renewal_key->status == WB_KEY_STATUS_SIGNING_KEY_VALID;
|
||||||
|
if (info->has_renewal) {
|
||||||
|
info->renewal_client = whitebox->renewal_key->client;
|
||||||
|
}
|
||||||
|
info->version = kExportedVersion;
|
||||||
|
info->num_content_keys = whitebox->content_keys.size();
|
||||||
|
info->num_generic_keys = whitebox->generic_keys.size();
|
||||||
|
size_t i = 0;
|
||||||
|
for (const auto& dict : {whitebox->content_keys, whitebox->generic_keys}) {
|
||||||
|
for (const auto& pair : dict) {
|
||||||
|
auto& key = info->keys[i];
|
||||||
|
CHECK(pair.first.size() <= sizeof(key.key_id));
|
||||||
|
|
||||||
|
memcpy(key.key_id.data(), pair.first.data(), pair.first.size());
|
||||||
|
key.key_id_size = pair.first.size();
|
||||||
|
key.key = pair.second;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return WB_RESULT_OK;
|
||||||
|
#else
|
||||||
|
return WB_RESULT_NOT_IMPLEMENTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
WB_Result WB_CONCAT_VERSION(WB_License_SignLicenseRequest_Init)() {
|
||||||
sign_license_request_initialized = true;
|
sign_license_request_initialized = true;
|
||||||
return WB_RESULT_OK;
|
return WB_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_SignLicenseRequest)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* license_request,
|
const uint8_t* license_request,
|
||||||
size_t license_request_size,
|
size_t license_request_size,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
@@ -423,7 +555,7 @@ WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox,
|
|||||||
return WB_RESULT_OK;
|
return WB_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_ProcessLicenseResponse_Init() {
|
WB_Result WB_CONCAT_VERSION(WB_License_ProcessLicenseResponse_Init)() {
|
||||||
if (!sign_license_request_initialized) {
|
if (!sign_license_request_initialized) {
|
||||||
return WB_RESULT_INVALID_STATE;
|
return WB_RESULT_INVALID_STATE;
|
||||||
}
|
}
|
||||||
@@ -432,7 +564,8 @@ WB_Result WB_License_ProcessLicenseResponse_Init() {
|
|||||||
return WB_RESULT_OK;
|
return WB_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_ProcessLicenseResponse)(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
WB_LicenseKeyMode license_key_mode,
|
WB_LicenseKeyMode license_key_mode,
|
||||||
const uint8_t* core_message,
|
const uint8_t* core_message,
|
||||||
size_t core_message_size,
|
size_t core_message_size,
|
||||||
@@ -583,6 +716,7 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
|||||||
GetODKContext(combined_message_str, core_message_size, &odk_context);
|
GetODKContext(combined_message_str, core_message_size, &odk_context);
|
||||||
|
|
||||||
if (result != WB_RESULT_OK) {
|
if (result != WB_RESULT_OK) {
|
||||||
|
DVLOG(1) << "Failed to get ODK context.";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -604,6 +738,7 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
|||||||
whitebox->provider_keys, provider_key_id);
|
whitebox->provider_keys, provider_key_id);
|
||||||
|
|
||||||
if (result != WB_RESULT_OK) {
|
if (result != WB_RESULT_OK) {
|
||||||
|
DVLOG(1) << "Failed to parse license.";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,7 +762,8 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
|||||||
return WB_RESULT_OK;
|
return WB_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_LoadEntitledContentKey(WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_LoadEntitledContentKey)(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* entitlement_key_id,
|
const uint8_t* entitlement_key_id,
|
||||||
size_t entitlement_key_id_size,
|
size_t entitlement_key_id_size,
|
||||||
const uint8_t* content_key_id,
|
const uint8_t* content_key_id,
|
||||||
@@ -647,6 +783,10 @@ WB_Result WB_License_LoadEntitledContentKey(WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: key data too small.";
|
DVLOG(1) << "Invalid parameter: key data too small.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (entitlement_key_id_size > 16 || content_key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
if (!whitebox->initialized) {
|
if (!whitebox->initialized) {
|
||||||
DVLOG(1) << "Invalid state: no license loaded.";
|
DVLOG(1) << "Invalid state: no license loaded.";
|
||||||
@@ -691,7 +831,8 @@ WB_Result WB_License_LoadEntitledContentKey(WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_RemoveEntitledContentKey(WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_RemoveEntitledContentKey)(
|
||||||
|
WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* content_key_id,
|
const uint8_t* content_key_id,
|
||||||
size_t content_key_id_size) {
|
size_t content_key_id_size) {
|
||||||
#ifndef HAS_ENTITLEMENT
|
#ifndef HAS_ENTITLEMENT
|
||||||
@@ -701,6 +842,10 @@ WB_Result WB_License_RemoveEntitledContentKey(WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: null pointer.";
|
DVLOG(1) << "Invalid parameter: null pointer.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (content_key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
if (!whitebox->initialized) {
|
if (!whitebox->initialized) {
|
||||||
DVLOG(1) << "Invalid state: no license loaded.";
|
DVLOG(1) << "Invalid state: no license loaded.";
|
||||||
return WB_RESULT_INVALID_STATE;
|
return WB_RESULT_INVALID_STATE;
|
||||||
@@ -719,7 +864,8 @@ WB_Result WB_License_RemoveEntitledContentKey(WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_QueryKeyStatus(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_QueryKeyStatus)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
WB_KeyQueryType type,
|
WB_KeyQueryType type,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
@@ -728,6 +874,10 @@ WB_Result WB_License_QueryKeyStatus(const WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: null pointer.";
|
DVLOG(1) << "Invalid parameter: null pointer.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
if (!whitebox->initialized) {
|
if (!whitebox->initialized) {
|
||||||
DVLOG(1) << "Invalid state: no license loaded.";
|
DVLOG(1) << "Invalid state: no license loaded.";
|
||||||
@@ -791,7 +941,8 @@ WB_Result WB_License_QueryKeyStatus(const WB_License_Whitebox* whitebox,
|
|||||||
return WB_RESULT_INVALID_PARAMETER; // Unknown query type.
|
return WB_RESULT_INVALID_PARAMETER; // Unknown query type.
|
||||||
}
|
}
|
||||||
|
|
||||||
static WB_Result WB_License_SignCommon(const WB_License_Whitebox* whitebox,
|
static WB_Result WB_License_SignCommon(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
size_t message_size,
|
size_t message_size,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
@@ -844,7 +995,8 @@ static WB_Result WB_License_SignCommon(const WB_License_Whitebox* whitebox,
|
|||||||
return WB_RESULT_OK;
|
return WB_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_SignRenewalRequest)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
size_t message_size,
|
size_t message_size,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
@@ -853,7 +1005,8 @@ WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox,
|
|||||||
signature_size, /* sha256= */ true);
|
signature_size, /* sha256= */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_SignPstReport(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_SignPstReport)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
size_t message_size,
|
size_t message_size,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
@@ -866,7 +1019,8 @@ WB_Result WB_License_SignPstReport(const WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_VerifyRenewalResponse)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
size_t message_size,
|
size_t message_size,
|
||||||
const uint8_t* signature,
|
const uint8_t* signature,
|
||||||
@@ -916,7 +1070,8 @@ WB_Result WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox,
|
|||||||
return WB_RESULT_OK;
|
return WB_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GetSecretString)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
WB_CipherMode mode,
|
WB_CipherMode mode,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
@@ -954,6 +1109,10 @@ WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: array size 0.";
|
DVLOG(1) << "Invalid parameter: array size 0.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
// The secret string can differ between keys, so we need to make sure that
|
// The secret string can differ between keys, so we need to make sure that
|
||||||
// the key id is actually a content key.
|
// the key id is actually a content key.
|
||||||
@@ -981,7 +1140,8 @@ WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_GenericEncrypt(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GenericEncrypt)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
const uint8_t* input_data,
|
const uint8_t* input_data,
|
||||||
@@ -1010,6 +1170,10 @@ WB_Result WB_License_GenericEncrypt(const WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: array size 0.";
|
DVLOG(1) << "Invalid parameter: array size 0.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = whitebox->generic_keys.find({key_id, key_id + key_id_size});
|
auto it = whitebox->generic_keys.find({key_id, key_id + key_id_size});
|
||||||
if (it == whitebox->generic_keys.end()) {
|
if (it == whitebox->generic_keys.end()) {
|
||||||
@@ -1038,7 +1202,8 @@ WB_Result WB_License_GenericEncrypt(const WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_GenericDecrypt(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GenericDecrypt)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
const uint8_t* input_data,
|
const uint8_t* input_data,
|
||||||
@@ -1067,6 +1232,10 @@ WB_Result WB_License_GenericDecrypt(const WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: array size 0.";
|
DVLOG(1) << "Invalid parameter: array size 0.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = whitebox->generic_keys.find({key_id, key_id + key_id_size});
|
auto it = whitebox->generic_keys.find({key_id, key_id + key_id_size});
|
||||||
if (it == whitebox->generic_keys.end()) {
|
if (it == whitebox->generic_keys.end()) {
|
||||||
@@ -1095,7 +1264,8 @@ WB_Result WB_License_GenericDecrypt(const WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_GenericSign(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GenericSign)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
@@ -1127,6 +1297,10 @@ WB_Result WB_License_GenericSign(const WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: array size 0.";
|
DVLOG(1) << "Invalid parameter: array size 0.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = whitebox->generic_keys.find({key_id, key_id + key_id_size});
|
auto it = whitebox->generic_keys.find({key_id, key_id + key_id_size});
|
||||||
if (it == whitebox->generic_keys.end()) {
|
if (it == whitebox->generic_keys.end()) {
|
||||||
@@ -1149,7 +1323,8 @@ WB_Result WB_License_GenericSign(const WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_GenericVerify(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_GenericVerify)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
const uint8_t* message,
|
const uint8_t* message,
|
||||||
@@ -1173,6 +1348,10 @@ WB_Result WB_License_GenericVerify(const WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: array size 0.";
|
DVLOG(1) << "Invalid parameter: array size 0.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = whitebox->generic_keys.find({key_id, key_id + key_id_size});
|
auto it = whitebox->generic_keys.find({key_id, key_id + key_id_size});
|
||||||
if (it == whitebox->generic_keys.end()) {
|
if (it == whitebox->generic_keys.end()) {
|
||||||
@@ -1197,7 +1376,8 @@ WB_Result WB_License_GenericVerify(const WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_Decrypt)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
WB_CipherMode mode,
|
WB_CipherMode mode,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
@@ -1221,6 +1401,10 @@ WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: array size 0.";
|
DVLOG(1) << "Invalid parameter: array size 0.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
const auto* content_key = FindKey(whitebox, key_id, key_id_size);
|
const auto* content_key = FindKey(whitebox, key_id, key_id_size);
|
||||||
|
|
||||||
@@ -1246,7 +1430,8 @@ WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox,
|
|||||||
output_data_size);
|
output_data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox,
|
WB_Result WB_CONCAT_VERSION(WB_License_MaskedDecrypt)(
|
||||||
|
const WB_CONCAT_VERSION(WB_License_Whitebox) * whitebox,
|
||||||
WB_CipherMode mode,
|
WB_CipherMode mode,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_size,
|
size_t key_id_size,
|
||||||
@@ -1273,6 +1458,10 @@ WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox,
|
|||||||
DVLOG(1) << "Invalid parameter: array size 0.";
|
DVLOG(1) << "Invalid parameter: array size 0.";
|
||||||
return WB_RESULT_INVALID_PARAMETER;
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
if (key_id_size > 16) {
|
||||||
|
DVLOG(1) << "Invalid parameter: key id too big.";
|
||||||
|
return WB_RESULT_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
const auto* content_key = FindKey(whitebox, key_id, key_id_size);
|
const auto* content_key = FindKey(whitebox, key_id, key_id_size);
|
||||||
|
|
||||||
@@ -1322,7 +1511,7 @@ WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void WB_License_Unmask(const uint8_t* masked_data,
|
void WB_CONCAT_VERSION(WB_License_Unmask)(const uint8_t* masked_data,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
size_t size,
|
size_t size,
|
||||||
const uint8_t* secret_string,
|
const uint8_t* secret_string,
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ WB_Result OdkLicenseParser::Parse(const std::string& decryption_key,
|
|||||||
VLOG(3) << "Invalid key at index " << i << " : no key id.";
|
VLOG(3) << "Invalid key at index " << i << " : no key id.";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (key_id.size() > 16) {
|
||||||
|
VLOG(3) << "Invalid key at index " << i << " : key id too big.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Add the key right away. The key will be invalid, so if we fail to
|
// Add the key right away. The key will be invalid, so if we fail to
|
||||||
// parse the key, we'll already have an entry for the invalid key.
|
// parse the key, we'll already have an entry for the invalid key.
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ WB_Result ProtobufLicenseParser::Parse(
|
|||||||
kEnableHwVerification && IsPlatformHardwareVerified(license);
|
kEnableHwVerification && IsPlatformHardwareVerified(license);
|
||||||
|
|
||||||
for (const auto& key : license.key()) {
|
for (const auto& key : license.key()) {
|
||||||
|
if (key.id().size() > 16) {
|
||||||
|
VLOG(3) << "Skipping key : key id too big.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// The default `type()` value will be SIGNING when not present in the
|
// The default `type()` value will be SIGNING when not present in the
|
||||||
// protobuf.
|
// protobuf.
|
||||||
switch (key.type()) {
|
switch (key.type()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user