diff --git a/tools/call_crypt_shared.sh b/tools/call_crypt_shared.sh new file mode 100755 index 000000000..2f5b24ca9 --- /dev/null +++ b/tools/call_crypt_shared.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +uv run "$(dirname "${BASH_SOURCE[0]}")/call_crypt_shared/call_crypt_shared.py" "$@" diff --git a/tools/call_crypt_shared/README.md b/tools/call_crypt_shared/README.md new file mode 100644 index 000000000..6138983aa --- /dev/null +++ b/tools/call_crypt_shared/README.md @@ -0,0 +1,27 @@ +# call_crypt_shared + +Test the [Crypt Shared](https://www.mongodb.com/try/download/enterprise-advanced/releases) library. + +The library is referred to as "Crypt Shared" on the and is often referred to as `crypt_shared` in code. The library file name is `mongo_crypt_v1.(dylib|so|dll)`. + +This tool is not a supported product and has no stability guarantees. + +## Usage + +```bash +# Print library version: +./tools/call_crypt_shared.sh --version --lib $HOME/bin/mongodl/crypt_shared/8.3.2/lib/mongo_crypt_v1.dylib +# mongo_crypt_v1-dev-8.3.2 + +# Mark up a command (reads from stdin): +cat ./tools/call_crypt_shared/tests/find.yml | ./tools/call_crypt_shared.sh --lib $HOME/bin/mongodl/crypt_shared/8.3.2/lib/mongo_crypt_v1.dylib +# (JSON output) + +# Mark up a command from a file: +./tools/call_crypt_shared.sh --cmd ./tools/call_crypt_shared/tests/find.yml --lib $HOME/bin/mongodl/crypt_shared/8.3.2/lib/mongo_crypt_v1.dylib +# (JSON output) + +# Use CRYPT_SHARED_LIB_PATH env var instead of --lib: +CRYPT_SHARED_LIB_PATH=$HOME/bin/mongodl/crypt_shared/8.3.2/lib/mongo_crypt_v1.dylib ./tools/call_crypt_shared.sh --version +# mongo_crypt_v1-dev-8.3.2 +``` diff --git a/tools/call_crypt_shared/call_crypt_shared.py b/tools/call_crypt_shared/call_crypt_shared.py new file mode 100755 index 000000000..7394bf2b8 --- /dev/null +++ b/tools/call_crypt_shared/call_crypt_shared.py @@ -0,0 +1,258 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.8" +# dependencies = [ +# "pymongo", +# "cffi", +# "pyyaml", +# ] +# /// + +import argparse +import bson +from bson import binary, json_util +import os +import re +import sys +import yaml +import json +import cffi +from pathlib import Path + + +ffi = cffi.FFI() + + +def _preprocess_header(header_path: str) -> str: + lines = [] + ifcount = 0 + with open(header_path, "r") as f: + for line in f: + line = line.rstrip("\n") + if line in ( + "#ifndef MONGO_CRYPT_SUPPORT_H", + "#endif // MONGO_CRYPT_SUPPORT_H", + ): + continue + if re.match(r"^#if", line): + ifcount += 1 + continue + if re.match(r"^#end", line): + ifcount -= 1 + continue + if ifcount > 0: + continue + if re.match(r"^#", line): + continue + line = re.sub(r"MONGO_CRYPT_API ", "", line) + line = re.sub(r"MONGO_API_CALL( ?)", "", line) + lines.append(line) + return "\n".join(lines) + + +# lib is the returned object from ffi.dlopen. +_lib = None + + +class _mongo_crypt_v1_status_Wrapper: + def __init__(self): + self._cdata = _lib.mongo_crypt_v1_status_create() + + def __enter__(self): + return self + + def cdata(self) -> cffi.FFI.CData: + return self._cdata + + def get_explanation(self): + got = _lib.mongo_crypt_v1_status_get_explanation(self._cdata) + return ffi.string(got) + + def __exit__(self, exc_type, exc_val, exc_tb): + _lib.mongo_crypt_v1_status_destroy(self._cdata) + + +class _mongo_crypt_v1_lib_Wrapper: + def __init__(self): + with _mongo_crypt_v1_status_Wrapper() as status: + self._cdata = _lib.mongo_crypt_v1_lib_create(status.cdata()) + if not self._cdata: + raise Exception( + "error in mongo_crypt_v1_lib_create: {}".format( + status.get_explanation() + ) + ) + + def __enter__(self): + return self + + def cdata(self) -> cffi.FFI.CData: + return self._cdata + + def __exit__(self, exc_type, exc_val, exc_tb): + with _mongo_crypt_v1_status_Wrapper() as status: + got = _lib.mongo_crypt_v1_lib_destroy(self._cdata, status.cdata()) + if got != _lib.MONGO_CRYPT_V1_SUCCESS: + raise Exception( + "error in mongo_crypt_v1_lib_destroy: ({}): {}".format( + got, status.get_explanation() + ) + ) + + +class _mongo_crypt_v1_bson_Wrapper: + def __init__(self, cdata: cffi.FFI.CData): + self._cdata = cdata + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + _lib.mongo_crypt_v1_bson_free(self._cdata) + + +class _mongo_crypt_v1_query_analyzer_Wrapper: + def __init__(self, crypt: _mongo_crypt_v1_lib_Wrapper): + with _mongo_crypt_v1_status_Wrapper() as status: + self._cdata = _lib.mongo_crypt_v1_query_analyzer_create( + crypt.cdata(), status.cdata() + ) + if self._cdata == ffi.NULL: + raise Exception( + "error in mongo_crypt_v1_query_analyzer_create: {}".format( + status.get_explanation() + ) + ) + + def __enter__(self): + return self + + def analyze_query(self, cmd_bytes: bytes, ns: str): + with _mongo_crypt_v1_status_Wrapper() as status: + documentBSON = ffi.new("uint8_t[]", cmd_bytes) + ns_bytes = ns.encode("utf8") + ns_cdata = ffi.new("char[]", ns_bytes) + ns_len = ffi.cast("uint32_t", len(ns_bytes)) + bson_len_ptr = ffi.new("uint32_t*") + got = _lib.mongo_crypt_v1_analyze_query( + self._cdata, + documentBSON, + ns_cdata, + ns_len, + bson_len_ptr, + status.cdata(), + ) + if got == ffi.NULL: + raise Exception( + "error in mongo_crypt_v1_analyze_query: {}".format( + status.get_explanation() + ) + ) + with _mongo_crypt_v1_bson_Wrapper(got): + got_bson = bson.decode(ffi.buffer(got, bson_len_ptr[0])) + return got_bson + + def __exit__(self, exc_type, exc_val, exc_tb): + _lib.mongo_crypt_v1_query_analyzer_destroy(self._cdata) + + +class _lib_Wrapper: + def __init__(self, lib: str): + global _lib + _lib = ffi.dlopen(lib) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + ffi.dlclose(_lib) + + +_parsed_header = False + + +def _parse_header(): + global _parsed_header + if _parsed_header: + return + header_path = Path(__file__).resolve().parent / "mongo_crypt.h" + ffi.cdef(_preprocess_header(header_path)) + _parsed_header = True + + +_json_options = json_util.JSONOptions( + json_mode=json_util.JSONMode.CANONICAL, + uuid_representation=binary.UuidRepresentation.STANDARD, +) + + +def analyze_query(lib: str, cmd_bytes: bytes, ns: str): + global _json_options + _parse_header() + with _lib_Wrapper(lib): + with _mongo_crypt_v1_lib_Wrapper() as crypt: + with _mongo_crypt_v1_query_analyzer_Wrapper(crypt) as qa: + got = qa.analyze_query(cmd_bytes, ns) + return json_util.dumps(got, json_options=_json_options, indent=4) + + +def get_version(lib: str): + _parse_header() + with _lib_Wrapper(lib): + version_cdata = _lib.mongo_crypt_v1_get_version_str() + version = ffi.string(version_cdata) + return version.decode("utf8") + + +def main(): + global _json_options + + parser = argparse.ArgumentParser() + parser.add_argument( + "--version", action="store_true", help="Print version of crypt shared library" + ) + parser.add_argument( + "--lib", + help="Path to the crypt shared library. May be passed as the environment variable CRYPT_SHARED_LIB_PATH.", + ) + parser.add_argument( + "--cmd", + help="Path to a file containing the command to analyze. The format must be extended canonical JSON. If not present, input is read from stdin.", + ) + parser.add_argument( + "--ns", + help="The namespace of the command. Defaults to test.test", + default="test.test", + ) + args = parser.parse_args() + + lib = os.getenv("CRYPT_SHARED_LIB_PATH", args.lib) + if not lib: + print( + "Error: --lib argument or CRYPT_SHARED_LIB_PATH environment variable must be provided.", + file=sys.stderr, + ) + sys.exit(1) + + if args.version: + print(get_version(lib)) + return + + # Read and transform input: YML => JSON => BSON + if args.cmd: + with open(args.cmd, "r") as infile: + as_yaml = yaml.safe_load(infile) + cmd_json = json.dumps(as_yaml) + else: + as_yaml = yaml.safe_load(sys.stdin) + cmd_json = json.dumps(as_yaml) + cmd_dict = json_util.loads(cmd_json, json_options=_json_options) + codec_options = bson.CodecOptions( + uuid_representation=binary.UuidRepresentation.STANDARD + ) + cmd_bson = bson.encode(cmd_dict, codec_options=codec_options) + print(analyze_query(lib, cmd_bson, args.ns)) + + +if __name__ == "__main__": + main() diff --git a/tools/call_crypt_shared/mongo_crypt.h b/tools/call_crypt_shared/mongo_crypt.h new file mode 100755 index 000000000..ef71dd77a --- /dev/null +++ b/tools/call_crypt_shared/mongo_crypt.h @@ -0,0 +1,323 @@ +/** + * Copyright (C) 2021-present MongoDB, Inc. and subject to applicable commercial license. + */ + +#pragma once + + +#ifndef MONGO_CRYPT_SUPPORT_H +#define MONGO_CRYPT_SUPPORT_H + +#include "mongo/util/modules.h" + +#include +#include + +#pragma push_macro("MONGO_API_CALL") +#undef MONGO_API_CALL + +#pragma push_macro("MONGO_API_IMPORT") +#undef MONGO_API_IMPORT + +#pragma push_macro("MONGO_API_EXPORT") +#undef MONGO_API_EXPORT + +#pragma push_macro("MONGO_CRYPT_SUPPORT_API") +#undef MONGO_CRYPT_SUPPORT_API + +#if defined(_WIN32) +#define MONGO_API_CALL __cdecl +#define MONGO_API_IMPORT __declspec(dllimport) +#define MONGO_API_EXPORT __declspec(dllexport) +#else +#define MONGO_API_CALL +#define MONGO_API_IMPORT __attribute__((visibility("default"))) +#define MONGO_API_EXPORT __attribute__((used, visibility("default"))) +#endif + +#if defined(MONGO_CRYPT_SUPPORT_STATIC) +#define MONGO_CRYPT_API +#else +#if defined(MONGO_CRYPT_SUPPORT_COMPILING) +#define MONGO_CRYPT_API MONGO_API_EXPORT +#else +#define MONGO_CRYPT_API MONGO_API_IMPORT +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An object which describes the details of the failure of an operation. + * + * The Mongo Crypt Shared Library uses allocated objects of this type to report the details of any + * failure, when an operation cannot be completed. Several `mongo_crypt_v1_status` functions are + * provided which permit observing the details of these failures. Further a construction function + * and a destruction function for these objects are also provided. + * + * The use of status objects from multiple threads is not thread safe unless all of the threads + * accessing a single status object are passing that object as a const-qualified (const + * mongo_crypt_v1_status *) pointer. If a single thread is passing a status object to a function + * taking it by non-const-qualified (mongo_crypt_v1_status*) pointer, then no other thread may + * access the status object. + * + * The `status` parameter is optional for all `mongo_crypt_v1_` functions that can take a status + * pointer. The caller may pass NULL instead of a valid `status` object, in which case the function + * will execute normally but will not provide any detailed error information in the caes of a + * failure. + * + * All `mongo_crypt_v1_status` functions can be used before the Mongo Crypt Shared library is + * initialized. This facilitates detailed error reporting from all library functions. + */ +typedef struct mongo_crypt_v1_status mongo_crypt_v1_status; + +/** + * Allocate and construct an API-return-status buffer object. + * + * Returns NULL when construction of a mongo_crypt_v1_status object fails. + * + * This function may be called before mongo_crypt_v1_lib_create(). + */ +MONGO_CRYPT_API mongo_crypt_v1_status* MONGO_API_CALL mongo_crypt_v1_status_create(void); + +/** + * Destroys a valid status object. + * + * The status object must be a valid mongo_crypt_v1_status object or NULL. + * + * This function is not thread safe, and it must not execute concurrently with any other function + * that accesses the status object being destroyed. It is, however, safe to destroy distinct status + * objects on distinct threads. + * + * This function does not report failures. + * + * This function may be called before `mongo_crypt_v1_lib_create()`. + * + * This function causes all storage associated with the specified status object to be released, + * including the storage referenced by functions that returned observable storage buffers from this + * status, such as strings. + */ +MONGO_CRYPT_API void MONGO_API_CALL mongo_crypt_v1_status_destroy(mongo_crypt_v1_status* status); + +/** + * The error codes reported by `mongo_crypt_v1` functions will be given the symbolic names as + * mapped by this enum. + * + * When a `mongo_crypt_v1` function fails (and it has been documented to report errors) it will + * report that error in the form of an `int` status code. That status code will always be returned + * as the type `int`; however, the values in this enum can be used to classify the failure. + */ +typedef enum { + MONGO_CRYPT_V1_ERROR_IN_REPORTING_ERROR = -2, + MONGO_CRYPT_V1_ERROR_UNKNOWN = -1, + + MONGO_CRYPT_V1_SUCCESS = 0, + + MONGO_CRYPT_V1_ERROR_ENOMEM = 1, + MONGO_CRYPT_V1_ERROR_EXCEPTION = 2, + MONGO_CRYPT_V1_ERROR_LIBRARY_ALREADY_INITIALIZED = 3, + MONGO_CRYPT_V1_ERROR_LIBRARY_NOT_INITIALIZED = 4, + MONGO_CRYPT_V1_ERROR_INVALID_LIB_HANDLE = 5, + MONGO_CRYPT_V1_ERROR_REENTRANCY_NOT_ALLOWED = 6, +} mongo_crypt_v1_error; + +/** + * Gets an error code from a `mongo_crypt_v1_status` object. + * + * When a `mongo_crypt_v1` function fails (and it has been documented to report errors) it will + * report its error in the form of an `int` status code which is stored into a supplied + * `mongo_crypt_v1_status` object, if provided. Some of these functions may also report extra + * information, which will be reported by other observer functions. Every `mongo_crypt_v1` + * function which reports errors will always update the `Error` code stored in a + * `mongo_crypt_v1_status` object, even upon success. + * + * This function does not report its own failures. + */ +MONGO_CRYPT_API int MONGO_API_CALL +mongo_crypt_v1_status_get_error(const mongo_crypt_v1_status* status); + +/** + * Gets a descriptive error message from a `mongo_crypt_v1_status` object. + * + * For failures where the error is MONGO_CRYPT_V1_ERROR_EXCEPTION, this returns a string + * representation of the internal C++ exception. + * + * The function to which the specified status object was passed must not have returned + * MONGO_CRYPT_V1_SUCCESS as its error code. + * + * The storage for the returned string is associated with the specified status object, and therefore + * it will be deallocated when the status is destroyed using mongo_crypt_v1_status_destroy(). + * + * This function does not report its own failures. + */ +MONGO_CRYPT_API const char* MONGO_API_CALL +mongo_crypt_v1_status_get_explanation(const mongo_crypt_v1_status* status); + +/** + * Gets a status code from a `mongo_crypt_v1_status` object. + * + * Returns a numeric status code associated with the status parameter which indicates a sub-category + * of failure. + * + * For any status object that does not have MONGO_CRYPT_V1_ERROR_EXCEPTION as its error, the + * value of this code is unspecified. + * + * This function does not report its own failures. + */ +MONGO_CRYPT_API int MONGO_API_CALL +mongo_crypt_v1_status_get_code(const mongo_crypt_v1_status* status); + +/** + * An object which describes the runtime state of the Mongo Crypt Shared Library. + * + * The Mongo Crypt Shared Library uses allocated objects of this type to indicate the present state + * of the library. Some operations which the library provides need access to this object. Further a + * construction function and a destruction function for these objects are also provided. No more + * than a single object instance of this type may exist at any given time. + * + * The use of `mongo_crypt_v1_lib` objects from multiple threads is not thread safe unless all of + * the threads accessing a single `mongo_crypt_v1_lib` object are not destroying this object. If + * a single thread is passing a `mongo_crypt_v1_lib` to its destruction function, then no other + * thread may access the `mongo_crypt_v1_lib` object. + */ +typedef struct mongo_crypt_v1_lib mongo_crypt_v1_lib; + +/** + * Creates a mongo_crypt_v1_lib object, which stores context for the Mongo Crypt Shared library. A + * process should only ever have one mongo_crypt_v1_lib instance. + * + * On failure, returns NULL and populates the 'status' object if it is not NULL. + */ +MONGO_CRYPT_API mongo_crypt_v1_lib* MONGO_API_CALL +mongo_crypt_v1_lib_create(mongo_crypt_v1_status* status); + +/** + * Tears down the state of this library. Existing mongo_crypt_v1_status objects remain valid. + * Existing mongo_crypt_v1_query_analyzer objects created from this library MUST BE destroyed + * before destroying the library object. + * + * The 'lib' parameter must be a valid mongo_crypt_v1_lib instance and must not be NULL. + * + * The 'status' parameter may be NULL, but must be a valid mongo_crypt_v1_status instance if it + * is not NULL. + * + * Returns MONGO_CRYPT_V1_SUCCESS on success. + * + * Returns MONGO_CRYPT_V1_ERROR_LIBRARY_NOT_INITIALIZED and modifies 'status' if + * mongo_crypt_v1_lib_create() has not been called previously. + */ +MONGO_CRYPT_API int MONGO_API_CALL mongo_crypt_v1_lib_destroy(mongo_crypt_v1_lib* lib, + mongo_crypt_v1_status* status); + + +/** + * Returns a product version in 64-bit integer in four 16-bit words, from high to low: + * + * - Major version + * - Minor version + * - Revision + * - Reserved + * + * For example, version 6.2.1 would be encoded as: 0x0006000200010000 + * + */ +MONGO_CRYPT_API uint64_t MONGO_API_CALL mongo_crypt_v1_get_version(void); + +/** + * Returns a product version as a text string. The string should not be modified or released + * + * Examples: + * Dev Build/patch: mongo_crypt_v1-rhel80-6.2.1-alpha4-284-g8662e7d + * Release build: mongo_crypt_v1-rhel80-6.2.1 + */ +MONGO_CRYPT_API const char* MONGO_API_CALL mongo_crypt_v1_get_version_str(void); + + +/** + * A single query analyzer can be used across repeated calls to mongo_crypt_v1_analyze_query. + * + * It is not safe to simultaneously invoke mongo_crypt_v1_query_analyzer_create on the same + * query analyzer from multiple threads + * + * It is the client's responsibility to call mongo_crypt_v1_query_analyzer_destroy() to free up + * resources used by the query analyzer. Once a query analyzer is destroyed, it is not safe to + * call mongo_crypt_v1_analyze_query. + */ +typedef struct mongo_crypt_v1_query_analyzer mongo_crypt_v1_query_analyzer; + +/** + * Creates a mongo_crypt_v1_query_analyzer object, which stores a parsed collation. + * + * The 'lib' parameter must be a valid mongo_crypt_v1_lib instance and must not be NULL. + * + * On failure, it returns NULL and populates the 'status' object if it is not NULL. + */ +MONGO_CRYPT_API mongo_crypt_v1_query_analyzer* MONGO_API_CALL +mongo_crypt_v1_query_analyzer_create(mongo_crypt_v1_lib* lib, mongo_crypt_v1_status* status); + +/** + * Destroys a valid mongo_crypt_v1_query_analyzer object. + * + * This function is not thread safe, and it must not execute concurrently with any other function + * that accesses the collation object being destroyed including those that access a matcher, + * projection or update object which references the collation object. + * + * This function does not report failures. + */ +MONGO_CRYPT_API void MONGO_API_CALL +mongo_crypt_v1_query_analyzer_destroy(mongo_crypt_v1_query_analyzer* analyzer); + + +/** + * Analyzes the 'documentBSON' input document which includes a JSON schema for namespace 'ns_str' + * and returns a new BSON document that replaces fields that need encryption with BinData + * (subtype 6, first byte 0) placeholders. + * + * The input document must be a valid OP_MSG document supports aggregate, count, delete, distinct, + * explain, find, findAndModify, insert and update. + * In addition, the input document must include two additional top-level fields: + * - jsonSchema : document - contains a valid JSON schema + * - isRemoteSchema : bool - true if schema comes from MongoD as opposed to client-side + * + * The 'analyzer' and 'documentBSON' parameters must point to initialized objects of their + * respective types. + * + * When the analysis is successful, this function returns non-null value which points to a valid + * BSON document and updates bson_len with the length of the BSON document + */ +MONGO_CRYPT_API uint8_t* MONGO_API_CALL +mongo_crypt_v1_analyze_query(mongo_crypt_v1_query_analyzer* analyzer, + const uint8_t* documentBSON, + const char* ns_str, + uint32_t ns_len, + uint32_t* bson_len, + mongo_crypt_v1_status* status); + +/** + * Free the memory of a BSON buffer returned by mongo_crypt_v1_analyze_query(). This function can be + * safely called on a NULL pointer. + * + * This function can be called at any time to deallocate a BSON buffer and will not invalidate any + * library object. + */ +MONGO_CRYPT_API void MONGO_API_CALL mongo_crypt_v1_bson_free(uint8_t* bson); + +#ifdef __cplusplus +} // extern "C" +#endif + +#undef MONGO_CRYPT_SUPPORT_API +#pragma pop_macro("MONGO_CRYPT_SUPPORT_API") + +#undef MONGO_API_EXPORT +#pragma push_macro("MONGO_API_EXPORT") + +#undef MONGO_API_IMPORT +#pragma push_macro("MONGO_API_IMPORT") + +#undef MONGO_API_CALL +#pragma pop_macro("MONGO_API_CALL") + +#endif // MONGO_CRYPT_SUPPORT_H diff --git a/tools/call_crypt_shared/selftest.py b/tools/call_crypt_shared/selftest.py new file mode 100644 index 000000000..baa36461f --- /dev/null +++ b/tools/call_crypt_shared/selftest.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.8" +# dependencies = [ +# "pymongo", +# "cffi", +# "pyyaml", +# ] +# /// +import json +import os +import unittest +import yaml +from pathlib import Path + +import bson +from bson import binary, json_util +import call_crypt_shared + +if os.environ.get("CRYPT_SHARED_LIB") is None: + raise RuntimeError( + "CRYPT_SHARED_LIB environment variable must be set to the path of the crypt_shared library" + ) + + +class TestCallCryptShared(unittest.TestCase): + def test_get_version(self): + lib = os.environ["CRYPT_SHARED_LIB"] + got = call_crypt_shared.get_version(lib) + self.assertTrue(got.startswith("mongo_crypt_v1"), got) + + def test_analyze_query(self): + if "REGENERATE_GOLDEN_FILES" in os.environ: + print("Regenerating golden files") + for test_path in Path("tests").glob("*.yml"): + file_name = test_path.stem + + # Read and transform test file: YML => JSON => BSON + as_yaml = yaml.safe_load(test_path.open("r")) + cmd_json = json.dumps(as_yaml) + json_options = json_util.JSONOptions( + json_mode=json_util.JSONMode.CANONICAL, + uuid_representation=binary.UuidRepresentation.STANDARD, + ) + cmd_dict = json_util.loads(cmd_json, json_options=json_options) + codec_options = bson.CodecOptions( + uuid_representation=binary.UuidRepresentation.STANDARD + ) + cmd_bson = bson.encode(cmd_dict, codec_options=codec_options) + + lib = os.environ["CRYPT_SHARED_LIB"] + got_bson = call_crypt_shared.analyze_query(lib, cmd_bson, "test.test") + got_dict = json_util.loads(json.dumps(yaml.safe_load(got_bson))) + got_json = bson.json_util.dumps(got_dict, indent=2) + if "REGENERATE_GOLDEN_FILES" in os.environ: + Path(f"tests/{file_name}.golden.json").write_text(got_json) + else: + expect = Path(f"tests/{file_name}.golden.json").read_text() + self.maxDiff = None # To print big string + self.assertEqual(got_json, expect, msg=f"Failed to match: {file_name}") + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/call_crypt_shared/tests/find.golden.json b/tools/call_crypt_shared/tests/find.golden.json new file mode 100644 index 000000000..c6e71ba97 --- /dev/null +++ b/tools/call_crypt_shared/tests/find.golden.json @@ -0,0 +1,42 @@ +{ + "hasEncryptionPlaceholders": true, + "schemaRequiresEncryption": true, + "result": { + "find": "test", + "filter": { + "value": { + "$eq": { + "$binary": { + "base64": "A1gAAAAQdAACAAAAEGEAAgAAAAVraQAQAAAABBI0VngSNJh2EjQSNFZ4kBIFa3UAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHYAQOIBABJjbQAAAAAAAAAAAAA=", + "subType": "06" + } + } + } + }, + "encryptionInformation": { + "type": 1, + "schema": { + "test.test": { + "escCollection": "enxcol_.test.esc", + "ecocCollection": "enxcol_.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "value", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tools/call_crypt_shared/tests/find.yml b/tools/call_crypt_shared/tests/find.yml new file mode 100644 index 000000000..3ebb238a5 --- /dev/null +++ b/tools/call_crypt_shared/tests/find.yml @@ -0,0 +1,34 @@ +{ + "find": "test", + "filter": { + "value": 123456 + }, + "encryptionInformation": { + "type": 1, + "schema": { + "test.test": { + "escCollection": "enxcol_.test.esc", + "ecocCollection": "enxcol_.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "value", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + }, + "$db": "test" +} diff --git a/tools/call_crypt_shared/tests/insert.golden.json b/tools/call_crypt_shared/tests/insert.golden.json new file mode 100644 index 000000000..a1009a213 --- /dev/null +++ b/tools/call_crypt_shared/tests/insert.golden.json @@ -0,0 +1,42 @@ +{ + "hasEncryptionPlaceholders": true, + "schemaRequiresEncryption": true, + "result": { + "insert": "test", + "encryptionInformation": { + "type": 1, + "schema": { + "test.test": { + "escCollection": "enxcol_.test.esc", + "ecocCollection": "enxcol_.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "value", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ] + } + } + }, + "documents": [ + { + "value": { + "$binary": { + "base64": "A1gAAAAQdAABAAAAEGEAAgAAAAVraQAQAAAABBI0VngSNJh2EjQSNFZ4kBIFa3UAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHYAQOIBABJjbQAAAAAAAAAAAAA=", + "subType": "06" + } + } + } + ] + } +} \ No newline at end of file diff --git a/tools/call_crypt_shared/tests/insert.yml b/tools/call_crypt_shared/tests/insert.yml new file mode 100644 index 000000000..e4d31eb76 --- /dev/null +++ b/tools/call_crypt_shared/tests/insert.yml @@ -0,0 +1,36 @@ +{ + "insert": "test", + "documents": [ + { + "value": 123456 + } + ], + "encryptionInformation": { + "type": 1, + "schema": { + "test.test": { + "escCollection": "enxcol_.test.esc", + "ecocCollection": "enxcol_.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "value", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + }, + "$db": "test" +} diff --git a/tools/decode_payload.sh b/tools/decode_payload.sh new file mode 100755 index 000000000..212a7b4a8 --- /dev/null +++ b/tools/decode_payload.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +uv run "$(dirname "${BASH_SOURCE[0]}")/decode_payload/decode_payload.py" "$@" diff --git a/tools/decode_payload/README.md b/tools/decode_payload/README.md new file mode 100644 index 000000000..9c59c2662 --- /dev/null +++ b/tools/decode_payload/README.md @@ -0,0 +1,344 @@ +# decode_payload + +Decode In-Use Encryption (IUE) payloads. + +This tool is not a supported product and has no stability guarantees. + +# Example Usage + +```bash +# Print name of payload: +./tools/decode_payload.sh ADgAAAAQYQABAAAABWtpABAAAAAEYWFhYWFhYWFhYWFhYWFhYQJ2AAwAAAA0NTctNTUtNTQ2MgAA +# FLE1EncryptionPlaceholder + +# Pass --json to dump JSON of payloads that wrap BSON: +./tools/decode_payload.sh --json ADgAAAAQYQABAAAABWtpABAAAAAEYWFhYWFhYWFhYWFhYWFhYQJ2AAwAAAA0NTctNTUtNTQ2MgAA +# { +# "name": "FLE1EncryptionPlaceholder", +# "dump": { +# "a": 1, +# "ki": { +# "$binary": { +# "base64": "YWFhYWFhYWFhYWFhYWFhYQ==", +# "subType": "04" +# } +# }, +# "v": "457-55-5462" +# } +# } + +# Use test directory for sample payloads: +./tools/decode_payload.sh $(cat ./tools/decode_payload/tests/payload2.b64) +# FLE1RandomEncryptedValue +``` + +# Explanation + +FLE1 refers to payloads for CSFLE. FLE2 refers to payloads for QE. See [Naming](https://github.com/mongodb/specifications/blob/9d0d3f0042a8cf5faeb47ae7765716151bfca9ef/source/client-side-encryption/client-side-encryption.md#naming). + +## FLE1EncryptionPlaceholder (0) + + + + + + + + + + + + + + +
Created bymongocryptd / crypt_shared
Intended forlibmongocrypt
ReferencesSpec / Server IDL / libmongocrypt
+ + +## FLE1DeterministicEncryptedValue (1) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
ReferencesSpec / libmongocrypt
+ +## FLE1RandomEncryptedValue (2) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
ReferencesSpec / libmongocrypt
+ +## FLE2EncryptionPlaceholder (3) + + + + + + + + + + + + + + +
Created bymongocryptd / crypt_shared
Intended forlibmongocrypt
ReferencesServer IDL / libmongocrypt
+ +## FLE2InsertUpdatePayload (4) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongocryptd / crypt_shared
ReferencesServer IDL / libmongocrypt
+ +## FLE2FindEqualityPayload (5) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
ReferencesServer IDL / libmongocrypt
+ +## FLE2UnindexedEncryptedValue (6) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
Referenceslibmongocrypt
+ +## FLE2IndexedEqualityEncryptedValue (7) + + + + + + + + + + + + + + +
Created bymongod / mongos
Intended forlibmongocrypt
Referenceslibmongocrypt
+ +## FLE2IndexedRangeEncryptedValue (9) + + + + + + + + + + + + + + +
Created bymongod / mongos
Intended forlibmongocrypt
Referenceslibmongocrypt
+ +## FLE2FindRangePayload (10) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
ReferencesServer IDL / libmongocrypt
+ +## FLE2InsertUpdatePayloadV2 (11) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
ReferencesServer IDL / libmongocrypt
+ +## FLE2FindEqualityPayloadV2 (12) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
ReferencesServer IDL / libmongocrypt
+ +## FLE2FindRangePayloadV2 (13) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
ReferencesServer IDL / libmongocrypt
+ +## FLE2EqualityIndexedValueV2 (14) + + + + + + + + + + + + + + +
Created bymongod / mongos
Intended forlibmongocrypt
Referenceslibmongocrypt
+ +## FLE2RangeIndexedValueV2 (15) + + + + + + + + + + + + + + +
Created bymongod / mongos
Intended forlibmongocrypt
Referenceslibmongocrypt
+ +## FLE2UnindexedEncryptedValueV2 (16) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
Referenceslibmongocrypt
+ +## FLE2IndexedTextEncryptedValue (17) + + + + + + + + + + + + + + +
Created bymongod / mongos
Intended forlibmongocrypt
Referenceslibmongocrypt
+ +## FLE2FindTextPayload (18) + + + + + + + + + + + + + + +
Created bylibmongocrypt
Intended formongod / mongos
ReferencesServer IDL / libmongocrypt
diff --git a/tools/decode_payload/decode_payload.py b/tools/decode_payload/decode_payload.py new file mode 100644 index 000000000..611c37ffa --- /dev/null +++ b/tools/decode_payload/decode_payload.py @@ -0,0 +1,68 @@ +# /// script +# dependencies = [ +# "pymongo", +# ] +# /// + +import base64 +import sys +import bson +import bson.json_util +import bson.errors +import argparse + + +def decode_payload(data): + blob_subtypes = { + 0: "FLE1EncryptionPlaceholder", + 1: "FLE1DeterministicEncryptedValue", + 2: "FLE1RandomEncryptedValue", + 3: "FLE2EncryptionPlaceholder", + 4: "FLE2InsertUpdatePayload", + 5: "FLE2FindEqualityPayload", + 6: "FLE2UnindexedEncryptedValue", + 7: "FLE2IndexedEqualityEncryptedValue", + 9: "FLE2IndexedRangeEncryptedValue", + 10: "FLE2FindRangePayload", + 11: "FLE2InsertUpdatePayloadV2", + 12: "FLE2FindEqualityPayloadV2", + 13: "FLE2FindRangePayloadV2", + 14: "FLE2EqualityIndexedValueV2", + 15: "FLE2RangeIndexedValueV2", + 16: "FLE2UnindexedEncryptedValueV2", + 17: "FLE2IndexedTextEncryptedValue", + 18: "FLE2FindTextPayload", + } + + blob_subtype = data[0] + + payload_name = blob_subtypes[blob_subtype] + + result = {"name": payload_name} + + # Some payloads are light wrappers around BSON. + try: + as_bson = bson.decode(data[1:]) + result["dump"] = as_bson + except bson.errors.InvalidBSON: + pass + + return result + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "--json", action="store_true", help="Print output in JSON format" + ) + + parser.add_argument("base64", type=str, help="base64 of a CSFLE/QE payload") + + args = parser.parse_args() + + data = base64.b64decode(args.base64) + result = decode_payload(data) + if args.json: + print(bson.json_util.dumps(result, indent=4)) + else: + print(result["name"]) diff --git a/tools/decode_payload/selftest.py b/tools/decode_payload/selftest.py new file mode 100644 index 000000000..a5f5a69ee --- /dev/null +++ b/tools/decode_payload/selftest.py @@ -0,0 +1,35 @@ +# /// script +# dependencies = [ +# "pymongo", +# ] +# /// + +import unittest +import base64 + +import bson +import decode_payload +import os +from pathlib import Path + + +class TestDecode(unittest.TestCase): + def test_decode(self): + if "REGENERATE_GOLDEN_FILES" in os.environ: + print("Regenerating golden files") + for test_path in Path("tests").glob("*.b64"): + file_name = test_path.stem + test_b64 = test_path.read_text() + test_data = base64.b64decode(test_b64) + got_dict = decode_payload.decode_payload(test_data) + got_json = bson.json_util.dumps(got_dict, indent=2) + if "REGENERATE_GOLDEN_FILES" in os.environ: + Path(f"tests/{file_name}.golden").write_text(got_json) + else: + expect = Path(f"tests/{file_name}.golden").read_text() + self.maxDiff = None # To print big string + self.assertEqual(got_json, expect, msg=f"Failed to match: {file_name}") + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/decode_payload/tests/payload0.b64 b/tools/decode_payload/tests/payload0.b64 new file mode 100644 index 000000000..61487c51e --- /dev/null +++ b/tools/decode_payload/tests/payload0.b64 @@ -0,0 +1 @@ +ADgAAAAQYQABAAAABWtpABAAAAAEYWFhYWFhYWFhYWFhYWFhYQJ2AAwAAAA0NTctNTUtNTQ2MgAA \ No newline at end of file diff --git a/tools/decode_payload/tests/payload0.golden b/tools/decode_payload/tests/payload0.golden new file mode 100644 index 000000000..fdb2134b3 --- /dev/null +++ b/tools/decode_payload/tests/payload0.golden @@ -0,0 +1,13 @@ +{ + "name": "FLE1EncryptionPlaceholder", + "dump": { + "a": 1, + "ki": { + "$binary": { + "base64": "YWFhYWFhYWFhYWFhYWFhYQ==", + "subType": "04" + } + }, + "v": "457-55-5462" + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload1.b64 b/tools/decode_payload/tests/payload1.b64 new file mode 100644 index 000000000..0d1501757 --- /dev/null +++ b/tools/decode_payload/tests/payload1.b64 @@ -0,0 +1 @@ +AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA== \ No newline at end of file diff --git a/tools/decode_payload/tests/payload1.golden b/tools/decode_payload/tests/payload1.golden new file mode 100644 index 000000000..bf2b2cae5 --- /dev/null +++ b/tools/decode_payload/tests/payload1.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE1DeterministicEncryptedValue" +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload10.b64 b/tools/decode_payload/tests/payload10.b64 new file mode 100644 index 000000000..e32d92fd4 --- /dev/null +++ b/tools/decode_payload/tests/payload10.b64 @@ -0,0 +1 @@ +CvEEAAADcGF5bG9hZADBBAAABGcAhQQAAAMwAH0AAAAFZAAgAAAAAKfR876j77BmHaWxFf7Px/B695Rn7JAN3upnEpaEqFT+BXMAIAAAAACXqoD16/Q8tNDRR7gP222DxV0SBOSZ4bqsxYILo8a/0wVjACAAAAAAFAp92kX7YI+mD8PNYqm41Kd3P11+jOfwGIyrjlrQBE0AAzEAfQAAAAVkACAAAAAAlpFiajzOojYERTN1LCni1VGk+ZVax/J2Rg3dQeHpMy4FcwAgAAAAAB4PqYOdB4uVsL2LSxWATz5EfrL573g4lDS0nQ+9uVVKBWMAIAAAAAApSFhK3ie+9R9s2A8nYTv1JyJVnRnNvOhnacqvh7A0uwADMgB9AAAABWQAIAAAAACEoDdR4neyFrwxEjf97csBWYgbGT2GqTlMff0Iww8S3wVzACAAAAAAO5caRM9/ghnb+v1iiAJSMEWFEURCoJ+/krcDaFXpJA8FYwAgAAAAADxh2OAhuAHS0y2k2gBHhmaf/QMM/bkmHOY57/h/hw5VAAMzAH0AAAAFZAAgAAAAACFSn9LbHIGoJEDxQm+l/VhB1Qp2sDHEDDH/n/c8F8n8BXMAIAAAAACBO4bhRYkAW8TOvy65UHl7YNTK+4vge++76cn1G8/dugVjACAAAAAAMfZI0QJuIjEP+2h7hMyADl63DLtAWXwO7ku694tjjwsAAzQAfQAAAAVkACAAAAAAGj22/+aFr+8l9CLnrDZ5NhzCgz++msotwjPmSF9OM+gFcwAgAAAAAC9cqJy///jAYzdKgtwFSx75wY+WX47DOOpPRbkb78OPBWMAIAAAAAB01fpGEYLy8nDFXUft76z/+9Z9KA2EiRcAQ97zr0u9lwADNQB9AAAABWQAIAAAAADbZ5AD/5OvYukqwD1ouIm1JCicqneF8Irq6sPhgRe20wVzACAAAAAAdP03rg0E4wfRAUdu6SaaQOZi4JxoX9bUAFENSuB38wQFYwAgAAAAAHyp8UBmXIbVgejUieOKpQHrfbHrGGRUnlaj59ojnBwjAAM2AH0AAAAFZAAgAAAAACSbt5cVtVjP7BGAWK09HRCwAyV9It3zsFV0xaSVTkCYBXMAIAAAAAB2oDy5xJX9PzwQxDkT/mZcL4L8MEH2iAQkbFRJX8uDnwVjACAAAAAA3zhqKXElNWg9l3x3N3W77heSWp/LAPfkhWYIj30yyt8AAzcAfQAAAAVkACAAAAAAPLjGwQ+DBcHE6XSH+knrIFTqq1zCgbltUvFW7wQwib0FcwAgAAAAAOfj/lP3YxmHoZBYlp60ZOnxx38JpMeougcNBUoWQfl0BWMAIAAAAABda0UNwhIuLtWxf8CqnFZLZTBCkgAj5eyyYhQd3W+hOgADOAB9AAAABWQAIAAAAADAg4r1xbwXaXEYn9Xc0gZ/ZTDqKRye52R4+M9yw1JoMwVzACAAAAAAPgpORYCcoS+SKCMf2IC1b7sHYFG0LtmWJmTlogsl81YFYwAgAAAAAB59AUYXsSm/LEx1Q35fiU44J+25wrdxZs1DrZCc+kRBAAAFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAABBwYXlsb2FkSWQA0gQAABBmaXJzdE9wZXJhdG9yAAEAAAAA \ No newline at end of file diff --git a/tools/decode_payload/tests/payload10.golden b/tools/decode_payload/tests/payload10.golden new file mode 100644 index 000000000..7e392345c --- /dev/null +++ b/tools/decode_payload/tests/payload10.golden @@ -0,0 +1,198 @@ +{ + "name": "FLE2FindRangePayload", + "dump": { + "payload": { + "g": [ + { + "d": { + "$binary": { + "base64": "p9HzvqPvsGYdpbEV/s/H8Hr3lGfskA3e6mcSloSoVP4=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "l6qA9ev0PLTQ0Ue4D9ttg8VdEgTkmeG6rMWCC6PGv9M=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "FAp92kX7YI+mD8PNYqm41Kd3P11+jOfwGIyrjlrQBE0=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "lpFiajzOojYERTN1LCni1VGk+ZVax/J2Rg3dQeHpMy4=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "Hg+pg50Hi5WwvYtLFYBPPkR+svnveDiUNLSdD725VUo=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "KUhYSt4nvvUfbNgPJ2E79SciVZ0ZzbzoZ2nKr4ewNLs=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "hKA3UeJ3sha8MRI3/e3LAVmIGxk9hqk5TH39CMMPEt8=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "O5caRM9/ghnb+v1iiAJSMEWFEURCoJ+/krcDaFXpJA8=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "PGHY4CG4AdLTLaTaAEeGZp/9Awz9uSYc5jnv+H+HDlU=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "IVKf0tscgagkQPFCb6X9WEHVCnawMcQMMf+f9zwXyfw=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "gTuG4UWJAFvEzr8uuVB5e2DUyvuL4Hvvu+nJ9RvP3bo=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "MfZI0QJuIjEP+2h7hMyADl63DLtAWXwO7ku694tjjws=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "Gj22/+aFr+8l9CLnrDZ5NhzCgz++msotwjPmSF9OM+g=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "L1yonL//+MBjN0qC3AVLHvnBj5ZfjsM46k9FuRvvw48=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "dNX6RhGC8vJwxV1H7e+s//vWfSgNhIkXAEPe869LvZc=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "22eQA/+Tr2LpKsA9aLiJtSQonKp3hfCK6urD4YEXttM=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "dP03rg0E4wfRAUdu6SaaQOZi4JxoX9bUAFENSuB38wQ=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "fKnxQGZchtWB6NSJ44qlAet9sesYZFSeVqPn2iOcHCM=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "JJu3lxW1WM/sEYBYrT0dELADJX0i3fOwVXTFpJVOQJg=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "dqA8ucSV/T88EMQ5E/5mXC+C/DBB9ogEJGxUSV/Lg58=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "3zhqKXElNWg9l3x3N3W77heSWp/LAPfkhWYIj30yyt8=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "PLjGwQ+DBcHE6XSH+knrIFTqq1zCgbltUvFW7wQwib0=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "5+P+U/djGYehkFiWnrRk6fHHfwmkx6i6Bw0FShZB+XQ=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "XWtFDcISLi7VsX/AqpxWS2UwQpIAI+XssmIUHd1voTo=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "wIOK9cW8F2lxGJ/V3NIGf2Uw6ikcnudkePjPcsNSaDM=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "PgpORYCcoS+SKCMf2IC1b7sHYFG0LtmWJmTlogsl81Y=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "Hn0BRhexKb8sTHVDfl+JTjgn7bnCt3FmzUOtkJz6REE=", + "subType": "00" + } + } + } + ], + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "cm": 0 + }, + "payloadId": 1234, + "firstOperator": 1 + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload11.b64 b/tools/decode_payload/tests/payload11.b64 new file mode 100644 index 000000000..19baefda0 --- /dev/null +++ b/tools/decode_payload/tests/payload11.b64 @@ -0,0 +1 @@ +C18BAAAFZAAgAAAAAHb62aV7+mqmaGcotPLdG3KP7S8diFwWMLM/5rYtqLrEBXMAIAAAAAAVJ6OWHRv3OtCozHpt3ZzfBhaxZirLv3B+G8PuaaO4EgVwADAAAAAAx0PWdXaep4jV5cRA2yQN+ULLwjv8e++oMonpfGOGs9BZ0uqPP7waiwZSwHsDx57+BXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AFAAAAAAq83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSHYikH9u4e644rfZY9N9UQR4h76qKAmcbo43utRcXMQy+FXXIxSuNntFHZHTcNJhJoFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsBWwAIAAAAABpn2zcb7jOd/FK3F45nBxnLU6HOMwZzmGOZ0w35v/DqRJrAAAAAAAAAAAAAA== \ No newline at end of file diff --git a/tools/decode_payload/tests/payload11.golden b/tools/decode_payload/tests/payload11.golden new file mode 100644 index 000000000..035260313 --- /dev/null +++ b/tools/decode_payload/tests/payload11.golden @@ -0,0 +1,49 @@ +{ + "name": "FLE2InsertUpdatePayloadV2", + "dump": { + "d": { + "$binary": { + "base64": "dvrZpXv6aqZoZyi08t0bco/tLx2IXBYwsz/mti2ousQ=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "FSejlh0b9zrQqMx6bd2c3wYWsWYqy79wfhvD7mmjuBI=", + "subType": "00" + } + }, + "p": { + "$binary": { + "base64": "x0PWdXaep4jV5cRA2yQN+ULLwjv8e++oMonpfGOGs9BZ0uqPP7waiwZSwHsDx57+", + "subType": "00" + } + }, + "u": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "t": 2, + "v": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSHYikH9u4e644rfZY9N9UQR4h76qKAmcbo43utRcXMQy+FXXIxSuNntFHZHTcNJhJo=", + "subType": "00" + } + }, + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "aZ9s3G+4znfxStxeOZwcZy1OhzjMGc5hjmdMN+b/w6k=", + "subType": "00" + } + }, + "k": 0 + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload12.b64 b/tools/decode_payload/tests/payload12.b64 new file mode 100644 index 000000000..030fa7d33 --- /dev/null +++ b/tools/decode_payload/tests/payload12.b64 @@ -0,0 +1 @@ +DIkAAAAFZAAgAAAAAPGmZcUzdE/FPILvRSyAScGvZparGI2y9rJ/vSBxgCujBXMAIAAAAACi1RjmndKqgnXy7xb22RzUbnZl1sOZRXPOC0KcJkAxmQVsACAAAAAApJtKPW4+o9B7gAynNLL26jtlB4+hq5TXResijcYet8USY20AAAAAAAAAAAAA \ No newline at end of file diff --git a/tools/decode_payload/tests/payload12.golden b/tools/decode_payload/tests/payload12.golden new file mode 100644 index 000000000..93e3c1da2 --- /dev/null +++ b/tools/decode_payload/tests/payload12.golden @@ -0,0 +1,24 @@ +{ + "name": "FLE2FindEqualityPayloadV2", + "dump": { + "d": { + "$binary": { + "base64": "8aZlxTN0T8U8gu9FLIBJwa9mlqsYjbL2sn+9IHGAK6M=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "otUY5p3SqoJ18u8W9tkc1G52ZdbDmUVzzgtCnCZAMZk=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "pJtKPW4+o9B7gAynNLL26jtlB4+hq5TXResijcYet8U=", + "subType": "00" + } + }, + "cm": 0 + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload13.b64 b/tools/decode_payload/tests/payload13.b64 new file mode 100644 index 000000000..cb4d3cb98 --- /dev/null +++ b/tools/decode_payload/tests/payload13.b64 @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/tools/decode_payload/tests/payload13.golden b/tools/decode_payload/tests/payload13.golden new file mode 100644 index 000000000..0fb949e84 --- /dev/null +++ b/tools/decode_payload/tests/payload13.golden @@ -0,0 +1,876 @@ +{ + "name": "FLE2FindRangePayloadV2", + "dump": { + "payload": { + "g": [ + { + "d": { + "$binary": { + "base64": "EH5NjAORbPyi5WXhDiggESVAqAYQOoyM89K/5NlLxgA=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "DC33fGVvcVYC/I6h9PsMHYQ/yrZ2+X4YdmTNIgFZkt0=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "YtpOd8Bd7k/b0zH8fsxlfmB/SwY0mcOqYsn4JIIuDQw=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "ffWVv+ysFys5eTN10LACdyWxHn/dCKMRWAQKzYmM5YE=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "YO/qaw0+92HAryxOUG7iK6hnIy3OaUA9jIqtHdvcq8Y=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "etRiPwDSFWBzpWSWkOKWM6fKStRJ8SyObnpc79ux8p0=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "8Ci9z02yMVsDNyHvLStLAHR25LO22UO5P/gbUG/IStQ=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "518WFoVWrUk+vd0h4ubURgpaBx5nuFnkUlPm7+Uv8j4=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "6lMlNYUhQywpqrM9nYT4Xn8wkoVFf2dsfuD/cXBsPK8=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "94NmrQlmFTl1tGGwm7yLbq6jSALMttdG5C/SpqlTJQA=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "VGEb7L0QCjV/PBTAvUyhlddo467ToKjlMdwI9hsjuE4=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "l7RsOFQfWxmV2cMZafTExrUJC43pyC/+L/peqek9Lf0=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "1A4pQT0U6YKgy9rYhiDjktlclfRwylRHU68jAWaMsNg=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "enciCpEPOpf/I/M3lnA2HlRkWCndFEs+k6Ny2zgQCrA=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "ELK0ExI0g4/WxNs+mf+Ua+mie3MuMO3daPGukA23VUY=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "RQp+fGA08v1bhcnYbfsP0ubXl9yg18QmYMfh2sd8EdE=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "GF7v3ATOcTb3y23TbHJEXtuTtrY0f2TBWDVM9jn+VPU=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "A4hleX/0UT5MKUq2TBhzQUmq5sMqlfkmFyO90Fvz5p8=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "Z1twqZkhU4JTzSmByR4SRwv73eQTFkKc7SF0AS9LAp4=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "C21qRBu2Px7VUz1lW95Dfn/0tw2yq9AVBtka34HijLg=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "/xLWzk4DlwlPogukD3gtqe4uxKX0GxEJYcG258VMxWs=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "lEha7oMjYtH7Y+LT05oFkSZLYUifIGcaz3B/0l/bCIg=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "aA6is49dasjn15eHXH5Jhh6mcV8gLJxpYAPcLCUVllE=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "IsDousyo/D8e4BCwUqvFhrKtOnpcGCSqpN94oFtWaC0=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "TSHu991yIUF6oiTU3XhlfD+PMVPRst9dw3KI9GyDhbg=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "dCm75t1SwaYbXfPzqYDbibSWiSS4RwQimSSXivhnLYQ=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "KfjHp8xww1JDjzyjTnfamOvjFDc1Z3Hp/v/ZuQnFOOE=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "Iv36tBHLLAhdrk+vuDZKcHSzQSMhy3s9C3OMSQDr1pw=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "8+eIpggm7v6kJGD/cFtn+aR6AUvhMgnvsbg8AtFE4mI=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "Kv602j4c3Bpn2t10qGl68eAD/fQsIH5lKMj8ANwrf7o=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "pMrQ0uFD/5j8czGNHAGVelckCECYKhZ/V9F5N6A+dWk=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "+wJVvj+BX0EuK/HexBLz1RD9XYkm61QwaoPGbzZdV0Q=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "TTSEkff+/JMBjNwUciY2RQ6M66uMQMAtwU+UidDv1y4=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "YxuA/GLZa7UCWqgMpODIGcJmWcKMebadrFFyLOQhtgk=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "zL0jN1Wc1ckRQn1L3C1wF0BUSMZYZtLdHVLJ2kWRuIY=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "I7uGriMAQc4A/a70Yi1Y7IAC7o/mfNYf7/FvwELYf80=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "+dnVt2atxfR+xLGWK5Kq8NtGrAiJWDS1inQ9WJFfSc4=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "KgXWRoPTu+Jp8MkBfpSC7csx3SzhKw4z0n/bDPBKgro=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "whuDsz+fCtqY8mW8QvEVQERjDChwrYTw4y7dinlCCOM=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "njQOZvkFRPUCVaN9cHjechsmAOf2sGD0UB5hHzRYrS8=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "DD6izA3TZpyswNx6uPfzZCX7Pv3I58o0gG5ojhVBORY=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "xbi7ql49Y4pduqWlLJqpwimRzrEnC7w5fWaMBiinHL8=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "Z6WeGpYzaBRXLg/lAT/Zl93uz0G6A+oH+1ydKwWDlfQ=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "FlIYn9xvjTL2d2DyweTjLiIXzxLulPCkfYE7yRc+biM=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "DEs8/aVSj2sJjxjv1K7o/aH8vZzt1bga73YiIKUx5DY=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "PXFfbALJ/VorUyhecEA99Yt4HGwkjaLTq1Zu6JgqASU=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "ltTVuEYm72NCUVMz7wpip1WxMvACEu9H5rGNPFoCThI=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "Qq9eIVoLcd4WxXUC3vub+EnxmcI2uP/yUWr3cz0jv9E=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "fBTUth4mZNyHrjSxO7dVFFF1CDhhntL0hF9VdYcRZTw=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "qM1ig9mJam0IgVVcCSqbXwFTPkdhTyT7V5MVRQIRzV0=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "n7LS0QzTv9sOJzxH0ZqxsLYBYoArEo/PIXkU/zTnpM0=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "cppOgCwgumYnIITTYjWLCYX8WJupo5vhvme167A5rJ8=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "T8WI0iuQyoLHVGa2foTOopHozwlCukamtJXqDeyjjNE=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "H9rPq5vvOIe9nTAcM1W1dVhQZ+gSkBohgoWLPcZnQXc=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "1MaIeolWrbyfuYxmwkPqAfFVCnUDrPzCBlVb7FX+WGY=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "QkeAX3TVcu1hPiMkN9dr2LiFtGhnF8a9iCPzGzc/GXQ=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "ng0GYpYJTypRLQUd5tIXWaAjZX5na04T/BypmwwrXPo=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "Gii6bOMSqn0e+936yfUvzY0jaJQZGXSddA0lMczujJU=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "4I8+S9rq7CuAvqV17CelxwAYcmpZY/bP70lIMV744os=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "PjlAM0tbO6EUmLAeIZt57YMkMsuQfuC3T3d9vtnxgjw=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "wDiOYTxTa4aRhR4qhhKVvba1+tGrZWWFXUmrWSfiFX0=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "xuHy3iVHCDT0m9aTHwAEiZLmLIEv+fRKv+dZhE/2O0U=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "mwwcWOnzvpxm4pROXOL+BlxjEG/7v7hIautb2ubFT44=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "rz8TdUfMczoqOnf0aMXL5yLUiJQbmjGHRbp6VX6iJfY=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "OPxeEPeMcW9k72XDHI4vw1Uxa2ZR/AS/x8w/OkUZqjQ=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "if3HPf6B1dTX/W+Vlp6ohadEQk/GAmHYzXfJia2zHeI=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "ZRf220s3VwKs6OXOyX8TqMTNCi200PDxmj3ids7XXfc=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "O7lbYRb1x/qWwa4EJp5D3KYhxRFQgItFgO7ALfbZbd4=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "znaMStSbtGXU1Pb5z9KDTvEd79s6gmWYCKOKdzeijpE=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "qdP+qDw3zlD0RC+kfsUGpSijEcWCsiOouUgOF69rZBI=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "RgCpBTCqEiK7wpVhe34paGDOnyPcUqjiVTUt3b+JcWM=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "gITE31hQA4ZOxpUFYSYv0mzWbd/6RKgbUXiUY96fBQE=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "dENENPaEmsnxf3MH0QtPbyrxmx+Riv3ZyFplhqSIuWo=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "E9C3uuzm5XQ7Wv0G9e3WH3bJT7CU3xo921gIAtCSIp4=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "MGDrqys8iJ3fCT2Cj+zXIuXtsf4OAXWJl5HoPUMlbNo=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "44lxSNg4TQqpxhLXJnfrfOCVBd+vddIP5Hl9YtKK8Og=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "Y3i3vrYN+5TWvg3VcbZQrWO+7VfT6nyeV+FxCq38LtA=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "lbpHiQAPLLTvSF+u58RBCLnYQKB5wciIQmANV9bkzso=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "zBY45pYMNhS6x0DWfKhoQHcLj/0ZGkU0ZqCz3kN2ngs=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "i67EFxliteX1uJjxFFyf/dG8td2hvu9u6liXqfECf1o=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "uThwsAsKUB56QAXC0MjJsZ9736atbiHPlK2tE0urf9Q=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "E9FcErTPxQA1y8wNae0GM33IXuIYw8tuFtoqu8fBymU=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "mZalrGDyG/snZh9NwcQ906khrEjaCOxFQstFYFtE6WI=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "D2uaBv8oc7l4EeC5PWx5sfeyGZoas0JdFJ33M3jjgjM=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "6f3/qlvOMjEUQCm6BpU69UperbewMIkQu/lS0s8Nkjc=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "hyMEg05aH9LxaIoBeHa23jP/K3ZY/+FN/Os0LDS7Txs=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "sYt/rXnpL55J9rlWSFRA4seaU6ggix7RgxbrJPu6gO4=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "gwIRLKS/lvl3qZiNTkOWc7vT2U4UJo2gkEu3MEiqaDg=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "7NQX7mrp+BLN50OJK9vQc4Xi0Q3Bb/vWtIDhpEhHKw4=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "5kW6i/jOBSdoGAsZEZxVNRvt6miv86bP8JfUT+1KJg8=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "VI+avbteAqFSRsS+8LoGvkrXDvbzQ1muuF3N9gX5gaM=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "79ofl6upDOzB2EyzAAkcG3tjMxh7uLHQeuxRsw0eh+E=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "KII0MMC7o6GKVfGo2qBW/p35NupBp7MI6Gp0zXYwJOc=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "9JX2qmu+U1kro5JBk3EqEmYEyzpAIoURIH+h4i8BLSI=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "PN+SYdtv6b2YCqGB+ioxPkUaWJGjNRt+U1qurqZZP64=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "162IdSb079yVlS7GkuSdHU3dOw03a+NS55ZPVBxbD08=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "axp0QEkVrH9SW09cHzob9g/GjqHfndlP6sLraIbLuqo=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "7PUz94fdX+m07hvEAkDAN2rQFRrPJNGY1c196TPBzQI=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "2ed4R4wYD6DT0P+N6o3gDJPE0DjljbRAv5vme3jb42s=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "DGB5yU2XT0fse/MPWgvBvZikVxrl5pf3S5K1hceKWoo=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "jFOaUscyM1pUMR8lte9F7PRIQ9YVEQEkJPqpMeyuWOg=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "JbMMwJfNftA7Xom8Bw/ghuZmSa3x12vTZxBUbV8m888=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "olj7z7umwXMlvlP4yD1RZvqAD1jw032P8wvaNmQ0M08=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "Nkf5wrUmHwopvPQc3VD0vg00BsGA5PtooRTxAUvIfso=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "aEQra7xyvA3JS0BasIpRVrz7ZXsp6RpH7OpfJBFzFG8=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "jiqv6wmJFqrBlGGd6cDMPu1Mqr6M/VpovICWffDUdC4=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "zWKale9zacDfk2tJrNUkYrvuljTjnRk/rMoIS/iQBYU=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "N07Fo9SK+fXp5Odk1J806pyVWc2WHXCtb1gJQknTgqs=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "hKA3UeJ3sha8MRI3/e3LAVmIGxk9hqk5TH39CMMPEt8=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "O5caRM9/ghnb+v1iiAJSMEWFEURCoJ+/krcDaFXpJA8=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "x+Oa2v1e1R7VomfsvcKO8VkY4eTl7LzjNQQL6Cj6GBQ=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "IVKf0tscgagkQPFCb6X9WEHVCnawMcQMMf+f9zwXyfw=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "gTuG4UWJAFvEzr8uuVB5e2DUyvuL4Hvvu+nJ9RvP3bo=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "zG6xXvdYOA8Myyt5WXWt0BWkQNQQtmstxsv5gCZsd54=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "Gj22/+aFr+8l9CLnrDZ5NhzCgz++msotwjPmSF9OM+g=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "L1yonL//+MBjN0qC3AVLHvnBj5ZfjsM46k9FuRvvw48=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "BhSDCzL78/uY6jz8VOCeitM7fALtBvmUHqgIqFonVYw=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "22eQA/+Tr2LpKsA9aLiJtSQonKp3hfCK6urD4YEXttM=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "dP03rg0E4wfRAUdu6SaaQOZi4JxoX9bUAFENSuB38wQ=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "cDsgTilc7TneMVqO8r/+ASX300fPG2QzYds6WSAejHk=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "JJu3lxW1WM/sEYBYrT0dELADJX0i3fOwVXTFpJVOQJg=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "dqA8ucSV/T88EMQ5E/5mXC+C/DBB9ogEJGxUSV/Lg58=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "9gBAm/VjmIxxyxjC3WYtk5garVKwbEaKA4ehcrTrV0A=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "PLjGwQ+DBcHE6XSH+knrIFTqq1zCgbltUvFW7wQwib0=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "5+P+U/djGYehkFiWnrRk6fHHfwmkx6i6Bw0FShZB+XQ=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "hM7MF/OTjXzQWgJHPIFNrhg37ABa0su5NuLJ6J8IJoc=", + "subType": "00" + } + } + }, + { + "d": { + "$binary": { + "base64": "wIOK9cW8F2lxGJ/V3NIGf2Uw6ikcnudkePjPcsNSaDM=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "PgpORYCcoS+SKCMf2IC1b7sHYFG0LtmWJmTlogsl81Y=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "vjiZ++YlRXaljBgRVEESlPFy9za1y7/XBgSaxLnTJu0=", + "subType": "00" + } + } + } + ], + "cm": 0 + }, + "payloadId": 1234, + "firstOperator": 1, + "sp": 1, + "tf": 6, + "mn": 0, + "mx": 1234567 + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload14.b64 b/tools/decode_payload/tests/payload14.b64 new file mode 100644 index 000000000..e44b90577 --- /dev/null +++ b/tools/decode_payload/tests/payload14.b64 @@ -0,0 +1 @@ +DhI0VngSNJh2EjQSNFZ4kBICFdoqcJBSkbiltLY0cy2tK2fj2LZsAu9PPZkUBWJ7e15oUGLjb1dDuIkOoC/bzGcgLarCTPPDtfZGbJ4/q+tDtmB+ubnLNxk+YXbGgERLQ0FP6alrZDpFuRs7G1ynlmo2gXQFMd3ykgzZpkDQLt8Har+HqOMbt7Gv14IZx08k+lONvmjnufpC7fkoytxJW1FGDQw7MXTfAbDosZhF2osYivHKZ6qiPoKDF+RMsjfjYo923p7eGUMhzZRwot8LaSOu \ No newline at end of file diff --git a/tools/decode_payload/tests/payload14.golden b/tools/decode_payload/tests/payload14.golden new file mode 100644 index 000000000..2f0d28a64 --- /dev/null +++ b/tools/decode_payload/tests/payload14.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE2EqualityIndexedValueV2" +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload15.b64 b/tools/decode_payload/tests/payload15.b64 new file mode 100644 index 000000000..46e55478a --- /dev/null +++ b/tools/decode_payload/tests/payload15.b64 @@ -0,0 +1 @@ +D6vN76sSNJh2EjQSNFZ4kBIQCKONPDzoIPJR6V3HiKEKizlmRU6wZ6BdgJWukp2SMCmnw1/ELG4J47sD0GavvaCbFwIxVipDqB0uGsY8VQZCKq/cWAE8YX90+1POSLR+ABjGqfWO8M7x78VrDWiHmSc/0b7olL3nZD8ozT01iUqxI3dOQVvJLVW72IhfZbFkvJRvGH0bBaIuwfyk6wit1RIUAzWFDWtGMlo4lZ08kpzhe0KUjyG7UKLg6yxf7DfdBV3bmiuFt+Xj8l1jx2kcYSyITXrB1Qqgkkumu6672WRLabi2SloAxuCfXmnvRuqLF5DEQ7fvAeE8tl8aSJ2pKKRVAbP3bwRsoJm91ErM7WVcJcTrTCR/lnAW8MmNjJCjSB56cgi91Q1s/XfeCgvNsiAexzTBKdNJSqw7RtSlsCwXhYSYSpbA9ohG5Z4Hx9eK5Eyi2+HEgqjq/8RPaVcqljVRuUxnIMxkBwu64H1UsoSxnQRGCs6sjO3UqhHupmckY2hOaod0gHsqRDUxOj6gYLzqx/egyCTMI+FKG8hN19MnKE2H3yv/PahY3uFM9FOnn9RXcKYtqixaj95WS4/nyAaVTDdrsJ8sWjZeq0EziVk31wYCAsZwgYp9Pu6Ur1JAhNwRkSs4O2CSbePsY8VZkWEG54ONaP9JZG3yidA3McUoyMvaNWlYTqWZc8nZMYjSqgfxgjrM0S8tEyyuwK4EEV6ez8pOxE+0JTgtyZdhrSztcljVITX6p3I/nuD6yWNpdRYdkK6QmVlMAm+OX7T6igIpu9dzYxJpeBD3b+ioXAXDSy6cYOamVyO+d+RgWSXT+ficAY2eUicHrsXZBgfReZiTXVqpQGNAi5HnI6f+UjeKqK7YsAw7TVLDFvNzgsFKH/OgoUIH3m2z6JFD8OcqF1ufFXsH5H54JLAzIIQZOBVztxuMqEkteFUxUIWOLw3uw3K8mZCv43QZYFvZcPTrN37qY6fTVxl375vFpJXCCpd4R8Dg4Q+JGrTk3UKcVoA4WkoQq9UTNMnOhesLhOt4M1igJwWjlZNM4E2iduXoP+gJ9l9tckybx0yjxJ2qCJyzz8sFv5m2tSHDELv6PXGxphhQnRYznnDsgJeAGh6KXqtuLJP4sUf8VjxFXaGD0TYx3WvRvmnQLCWfKnG+fr0slKl83Q== \ No newline at end of file diff --git a/tools/decode_payload/tests/payload15.golden b/tools/decode_payload/tests/payload15.golden new file mode 100644 index 000000000..49ea672e2 --- /dev/null +++ b/tools/decode_payload/tests/payload15.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE2RangeIndexedValueV2" +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload16.b64 b/tools/decode_payload/tests/payload16.b64 new file mode 100644 index 000000000..dec582458 --- /dev/null +++ b/tools/decode_payload/tests/payload16.b64 @@ -0,0 +1 @@ +EKvN76sSNJh2EjQSNFZ4kBICUH8j3oVCIjE3koejjIwxHF/nVP95ymiPNUPKskdjx55vK0SasqFyS4LxjZ6fQbzZSoMHPwdmR5otQl9HcMjAcg== \ No newline at end of file diff --git a/tools/decode_payload/tests/payload16.golden b/tools/decode_payload/tests/payload16.golden new file mode 100644 index 000000000..246f102aa --- /dev/null +++ b/tools/decode_payload/tests/payload16.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE2UnindexedEncryptedValueV2" +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload17.b64 b/tools/decode_payload/tests/payload17.b64 new file mode 100644 index 000000000..d8fc7448f --- /dev/null +++ b/tools/decode_payload/tests/payload17.b64 @@ -0,0 +1 @@ +ERI0VngSNJh2EjQSNFZ4kBICBQAAAAIAAAABAAAAZqAy0bSOXpYYlpKQxCYMoJiPnn1LGwTohBSMPC1+G93bEjHAlofOenlBB9n92xusO/oky0LQKXwWrUQGlgeGvr+a6dcJziqJgr94tT5e5FYQdipids631+ctrY6L6zV9NLwbMs5kBPPjnJf9uGsHfXDIaJb6Mp+vMCmhQBL+S3Q9ImfZi4iOkAbGgwOcGhNHuvGOUPAnBLFGv8AYz0GlV1KBX1PVeVxmrQ7S8r3n9kcdoLfv/KT+ITaV8qFqub4TZnj/kp9PB3sAlngv1Kw8KWu/Kv8lIKylWFz6jI0U1IHFcB6LLGhLJVkR18PhoPGpPXW4mU9vdiEJG9Bi2GxDmsDQg2sw4MnSTtgNIzoJ70QfPh8ItSXJ0mgrI+QyvG9YXeTAqznIfkyws6Y+Xqh4wQ5wWsxMWRJvhiU2zNeWg9MYubWD8j2lcTJE5M/57I+6WhKtu7dRP/AwRYak9M++MBSkIZF5p4YYz4iQgCYrS5Z4b7c9Syqyw5q1oJNNmzEGUU2UwHKWvmy9mvU7Re5FB8kjzcIwd5p1wzdy33uISqiY056xvhCODyhdzSqi8OKd2HoEh22275uI5DOOelby31JnznTSreIHj8XEwtLTQem/qSGRLido/+f4H9AqP8Jqd0rfMyK6EaedeL+Cd5yiiEVjtLLX2whPoSnOmztiiCEBFUrqzKPyYVhzzySnLPOaeRpDQix5xlCXEtzNqhYyMiot/wCkSM6wuYkYzRJ0/ug6fDPBpA/xdpP3jXhbM0vc \ No newline at end of file diff --git a/tools/decode_payload/tests/payload17.golden b/tools/decode_payload/tests/payload17.golden new file mode 100644 index 000000000..5671bacf6 --- /dev/null +++ b/tools/decode_payload/tests/payload17.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE2IndexedTextEncryptedValue" +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload18.b64 b/tools/decode_payload/tests/payload18.b64 new file mode 100644 index 000000000..36be6cd2f --- /dev/null +++ b/tools/decode_payload/tests/payload18.b64 @@ -0,0 +1 @@ +Er0AAAADdHMAhQAAAANlAH0AAAAFZAAgAAAAACgO2rQZB2PR9Bg9OD+IMHc4WcOnShMWEJTm/UTnOQ/tBXMAIAAAAADDyJgO0R5j7BmRBLyaCIkyLJ64DQDu4LUUjcg/fnittwVsACAAAAAAh3MyKiuebAiIbba8ZbRv/dZGUeiklACp5V/1vFUNRb8AABJjbQArAAAAAAAAAAhjZgABCGRmAAADcHMAFQAAABB1YgAUAAAAEGxiAAIAAAAAAA== \ No newline at end of file diff --git a/tools/decode_payload/tests/payload18.golden b/tools/decode_payload/tests/payload18.golden new file mode 100644 index 000000000..b5f496add --- /dev/null +++ b/tools/decode_payload/tests/payload18.golden @@ -0,0 +1,34 @@ +{ + "name": "FLE2FindTextPayload", + "dump": { + "ts": { + "e": { + "d": { + "$binary": { + "base64": "KA7atBkHY9H0GD04P4gwdzhZw6dKExYQlOb9ROc5D+0=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "w8iYDtEeY+wZkQS8mgiJMiyeuA0A7uC1FI3IP354rbc=", + "subType": "00" + } + }, + "l": { + "$binary": { + "base64": "h3MyKiuebAiIbba8ZbRv/dZGUeiklACp5V/1vFUNRb8=", + "subType": "00" + } + } + } + }, + "cm": 43, + "cf": true, + "df": false, + "ps": { + "ub": 20, + "lb": 2 + } + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload2.b64 b/tools/decode_payload/tests/payload2.b64 new file mode 100644 index 000000000..a01736ab3 --- /dev/null +++ b/tools/decode_payload/tests/payload2.b64 @@ -0,0 +1 @@ +Am2IfShB4k/NqP8INteqCxUCEikm46tQNyXYxnUWcZ2J7mXfvZFHvSfQwQoXgUPt9I2Q1h3aN1K4mkgOOfk7jaOGZtPRW3iVjaeRjUh9Xw3M+Q== \ No newline at end of file diff --git a/tools/decode_payload/tests/payload2.golden b/tools/decode_payload/tests/payload2.golden new file mode 100644 index 000000000..d4e21964b --- /dev/null +++ b/tools/decode_payload/tests/payload2.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE1RandomEncryptedValue" +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload3.b64 b/tools/decode_payload/tests/payload3.b64 new file mode 100644 index 000000000..bf54ec995 --- /dev/null +++ b/tools/decode_payload/tests/payload3.b64 @@ -0,0 +1 @@ +A1gAAAAQdAACAAAAEGEAAgAAAAVraQAQAAAABBI0VngSNJh2EjQSNFZ4kBIFa3UAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHYAQOIBABJjbQAAAAAAAAAAAAA= \ No newline at end of file diff --git a/tools/decode_payload/tests/payload3.golden b/tools/decode_payload/tests/payload3.golden new file mode 100644 index 000000000..5e9149c8f --- /dev/null +++ b/tools/decode_payload/tests/payload3.golden @@ -0,0 +1,21 @@ +{ + "name": "FLE2EncryptionPlaceholder", + "dump": { + "t": 2, + "a": 2, + "ki": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "ku": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "v": 123456, + "cm": 0 + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload4.b64 b/tools/decode_payload/tests/payload4.b64 new file mode 100644 index 000000000..3e5b87073 --- /dev/null +++ b/tools/decode_payload/tests/payload4.b64 @@ -0,0 +1 @@ +BG0BAAAFZAAgAAAAAIv6VUIIdmtHdpgZoJ3jI1ml1C2PRpbVhDZ+KLANYotkBXMAIAAAAAAYeqduU82pqo68MSIuOE8SLoa31j+2KEgNUJmOmMevGQVjACAAAAAAMMRH1V+7hgaihhDEhR70GldDZgQ8CDNasgLlI3T2EPUFcABQAAAAAI01AUQR/WmNQM9F0bCmYSUnlfWt/0VMG0TraZFQBTpVJ4WjJlaDS2hrCIVnlugzmeOisFFkx4ZvLGx5TXrwbJ0dRT011j1BxQHERAugUqeOBXUAEAAAAAQi4yMnD+xGdb8i/okx28IyEHQAAgAAAAV2AEkAAAAAIuMjJw/sRnW/Iv6JMdvCMnuKUnAoATZAj+50R9EyQIlO9G2HAEjOvfPb6g7OWYgFs1ogqzjXxeZDlSN1GfjQW3+nBMA6+KlrYgVlACAAAAAAOTxFECgSgD/PKSpuTxZx1vWmUY/E0XeZdG6Mk3Mmj9QA \ No newline at end of file diff --git a/tools/decode_payload/tests/payload4.golden b/tools/decode_payload/tests/payload4.golden new file mode 100644 index 000000000..2830002d6 --- /dev/null +++ b/tools/decode_payload/tests/payload4.golden @@ -0,0 +1,48 @@ +{ + "name": "FLE2InsertUpdatePayload", + "dump": { + "d": { + "$binary": { + "base64": "i/pVQgh2a0d2mBmgneMjWaXULY9GltWENn4osA1ii2Q=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "GHqnblPNqaqOvDEiLjhPEi6Gt9Y/tihIDVCZjpjHrxk=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "MMRH1V+7hgaihhDEhR70GldDZgQ8CDNasgLlI3T2EPU=", + "subType": "00" + } + }, + "p": { + "$binary": { + "base64": "jTUBRBH9aY1Az0XRsKZhJSeV9a3/RUwbROtpkVAFOlUnhaMmVoNLaGsIhWeW6DOZ46KwUWTHhm8sbHlNevBsnR1FPTXWPUHFAcREC6BSp44=", + "subType": "00" + } + }, + "u": { + "$binary": { + "base64": "IuMjJw/sRnW/Iv6JMdvCMg==", + "subType": "04" + } + }, + "t": 2, + "v": { + "$binary": { + "base64": "IuMjJw/sRnW/Iv6JMdvCMnuKUnAoATZAj+50R9EyQIlO9G2HAEjOvfPb6g7OWYgFs1ogqzjXxeZDlSN1GfjQW3+nBMA6+KlrYg==", + "subType": "00" + } + }, + "e": { + "$binary": { + "base64": "OTxFECgSgD/PKSpuTxZx1vWmUY/E0XeZdG6Mk3Mmj9Q=", + "subType": "00" + } + } + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload5.b64 b/tools/decode_payload/tests/payload5.b64 new file mode 100644 index 000000000..b947bdd67 --- /dev/null +++ b/tools/decode_payload/tests/payload5.b64 @@ -0,0 +1 @@ +BbEAAAAFZAAgAAAAAE8KGPgq7h3n9nH5lfHcia8wtOTLwGkZNLBesb6PULqbBXMAIAAAAACq0558QyD3c3jkR5k0Zc9UpQK8ByhXhtn2d1xVQnuJ3AVjACAAAAAA1003zUWGwD4zVZ0KeihnZOthS3V6CEHUfnJZcIYHefIFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA== \ No newline at end of file diff --git a/tools/decode_payload/tests/payload5.golden b/tools/decode_payload/tests/payload5.golden new file mode 100644 index 000000000..7fafe5a04 --- /dev/null +++ b/tools/decode_payload/tests/payload5.golden @@ -0,0 +1,30 @@ +{ + "name": "FLE2FindEqualityPayload", + "dump": { + "d": { + "$binary": { + "base64": "TwoY+CruHef2cfmV8dyJrzC05MvAaRk0sF6xvo9Qups=", + "subType": "00" + } + }, + "s": { + "$binary": { + "base64": "qtOefEMg93N45EeZNGXPVKUCvAcoV4bZ9ndcVUJ7idw=", + "subType": "00" + } + }, + "c": { + "$binary": { + "base64": "1003zUWGwD4zVZ0KeihnZOthS3V6CEHUfnJZcIYHefI=", + "subType": "00" + } + }, + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "cm": 0 + } +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload6.b64 b/tools/decode_payload/tests/payload6.b64 new file mode 100644 index 000000000..3f575895d --- /dev/null +++ b/tools/decode_payload/tests/payload6.b64 @@ -0,0 +1 @@ +BnjG/o5QT0VhmxzQeAbrhfwCfGsYmaa/rfV/k1h2jkJTh7S5xtIMxFzyK0lSIZenQJCepp5KrRY3dAGup9shwz9pOUF+cAh8KXuA \ No newline at end of file diff --git a/tools/decode_payload/tests/payload6.golden b/tools/decode_payload/tests/payload6.golden new file mode 100644 index 000000000..c217976c8 --- /dev/null +++ b/tools/decode_payload/tests/payload6.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE2UnindexedEncryptedValue" +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload7.b64 b/tools/decode_payload/tests/payload7.b64 new file mode 100644 index 000000000..a644cec34 --- /dev/null +++ b/tools/decode_payload/tests/payload7.b64 @@ -0,0 +1 @@ +B0ObNHrTR056kS3MSoY7omkCML5HhwnpVS7w9I8BkoUo16wWK9ito9wVIOYgq0/D5Gd/HtiwEJ3x3Uy1Qkgn6Nb2NrYz1LAKeBdK3/EmeUVOjAkWFXu9SnyCu071b1DRFrKw2eYhetsQILsyNiZfzuS8gJ5W7ArF5AjaVY71eS83kkIBhn39cAXB9dhOhb8hMV+iTJD/jQNGNlw/TMo436e5DspINqJ7ZE4tS/NKlP6F0nV6LW/hWHUe3ClCUhDH/OdkcwrYQ8gMYN9jdT4NCzB+DT8RO6lnV+Y= \ No newline at end of file diff --git a/tools/decode_payload/tests/payload7.golden b/tools/decode_payload/tests/payload7.golden new file mode 100644 index 000000000..96a7784e5 --- /dev/null +++ b/tools/decode_payload/tests/payload7.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE2IndexedEqualityEncryptedValue" +} \ No newline at end of file diff --git a/tools/decode_payload/tests/payload9.b64 b/tools/decode_payload/tests/payload9.b64 new file mode 100644 index 000000000..ea880173f --- /dev/null +++ b/tools/decode_payload/tests/payload9.b64 @@ -0,0 +1 @@ +CVkwKtDmKE4wmHqxJleVlkgQ6M6Fzuh68tGrCjKyAHq9M6tNsvO6BY8gnwWXlI/fHpDV/AjlPQA/bB4zz+GPulalwDYVuIKRecthdXAThkOVyIoJ1DnEqk2b3V7mZ00ZU8DIivKqTPtJWVfgCkUGufk/q0Y2zQ74jXvaHCSfJ2XzwHfmKCuEaKDqiPYGhMN1QqSmA/EJ9phTeASi8tLz4pq9dZx0Ad0xDUikxQWeZsr1oKn3RABKB0c3+SXie+tLp56KKkUvQQdv+iK+d77dFhRWgGXX4n53oyJrd8sinsc/BM7mdMxk/8B+0gQr2j0so7f2fqfnqz4szX1w7+ecYda2H1etE3gXODcTIrsu/p4V3ReKwkFgtF60z+ho2WW0F3PVKMgNieWNYuEYVRA8afm6b08YjJoHFGl43zL5Tm+eHCdj5fZ9eWdF8Ym1tV9W9ZPhtLYyFXKi/6q9nLSBJLxnQpiiTmvIuszMbMLBVN9xPMc7gLPw1KqXhHmLXla5o47nrDsfg9GwURGybTmGQ8GCyKrodD3hqwAyUd9ket+jwF6GOqATJEv839qHW06M6vtYJP1g7quCxAzHPlhC9bN3yixY2QWGkJCE9KiEA+wKq4tRkhKXvGCXHLwE+Xv6KJDD+dqbyArjgFZfU6b/o0NJVqsucNgfC5hoeKtK9ihoMvpCiY59J6idiwyYUhnONHJEaRQbyVempbAG4e4H5DbXGLWTLHyAJrgG3S9gXgT3AbdlU4Rq/XYX/ZIzBdkOt8d4T4UohPxvxLoKcO05RjTd3AhskhtQ6NPhvHp302egfwSAcUblJ5sYFdubs8109LRW8fr9GfU4tN0QSMudcxU6BgGldaSPHgzEqj9ne5MvGAA+62ZxNwBW4qBAyiUEut/J0fEm3sZ+kIJEyMo4KuG8s4zaBwDPRQ6BvzODmkfloiFXEQmeLPgaRQBdCw3gLmMlbRJ2mxQ4d6oW/REkqDZTxlmm9jnu/z5DrDgJc3kugHIib8BHe/MgUinestjj97jCwRLJw+iJ+Roo/HWL288nKGY/stokjHUY4BY0k1T77R+54kyeMPX9lL/jGbfoozJCDiSSxIBUbY6mDwoEtpmIyzrG/arT+cL/NmQW+CvgfQCQr+nk2+BdUmK1C8uqYJbBKmZHOYh5ugla0dDqP0ybLsiBKr2qUsG5nOq+/wdZe/K5Z7Xjv4vI2xCYdbTaIL6XfhM1cqV46B3tar4h4JVmNiglVuqC37h4gzhuA93/5ZB4e2E//Mnv5LKa9NCgV8/B2DLLt2FQRSfdQeiMUUjwd7VJTXAfhRiO3eGH171QBPGqdak9ek65WLvvHboyCYm/Wa42UTkIGq56kX6IBk/APgZCx76Kc5GdW4pT4dmUp9rwtq8CjmTA \ No newline at end of file diff --git a/tools/decode_payload/tests/payload9.golden b/tools/decode_payload/tests/payload9.golden new file mode 100644 index 000000000..ca3cae10f --- /dev/null +++ b/tools/decode_payload/tests/payload9.golden @@ -0,0 +1,3 @@ +{ + "name": "FLE2IndexedRangeEncryptedValue" +} \ No newline at end of file