Skip to content

Text search explicit encryption API and prose tests #2084

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .evergreen/scripts/compile-libmongocrypt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ compile_libmongocrypt() {
# `.evergreen/scripts/kms-divergence-check.sh` to ensure that there is no
# divergence in the copied files.

# Clone libmongocrypt and check-out 1.13.0.
git clone -q --depth=1 https://github.com/mongodb/libmongocrypt --branch 1.13.0 || return
# Clone libmongocrypt and check-out 1.15.0.
git clone -q --depth=1 https://github.com/mongodb/libmongocrypt --branch 1.15.0 || return

declare -a crypt_cmake_flags=(
"-DMONGOCRYPT_MONGOC_DIR=${mongoc_dir}"
"-DBUILD_TESTING=OFF"
"-DENABLE_ONLINE_TESTS=OFF"
"-DENABLE_MONGOC=OFF"
"-DBUILD_VERSION=1.13.0"
"-DBUILD_VERSION=1.15.0"
)

. "$(dirname "${BASH_SOURCE[0]}")/find-ccache.sh"
Expand Down
4 changes: 2 additions & 2 deletions src/libmongoc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -489,10 +489,10 @@ elseif (NOT ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL OFF)
find_package (mongocrypt QUIET)
endif ()

if (mongocrypt_FOUND AND "${mongocrypt_VERSION}" VERSION_LESS 1.13.0)
if (mongocrypt_FOUND AND "${mongocrypt_VERSION}" VERSION_LESS 1.15.0)
message (STATUS " libmongocrypt found at ${mongocrypt_DIR}")
message (STATUS " libmongocrypt version ${mongocrypt_VERSION} found")
message (STATUS " libmongocrypt version 1.13.0 is required to enable In-Use Encryption Support.")
message (STATUS " libmongocrypt version 1.15.0 is required to enable In-Use Encryption Support.")
set (REQUIRED_MONGOCRYPT_VERSION_FOUND OFF)
elseif (mongocrypt_FOUND)
set (REQUIRED_MONGOCRYPT_VERSION_FOUND ON)
Expand Down
186 changes: 185 additions & 1 deletion src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

#include <stdint.h>
#ifndef _WIN32
#include <sys/wait.h>

Expand Down Expand Up @@ -463,6 +464,26 @@ struct _mongoc_client_encryption_encrypt_range_opts_t {
} precision;
};

struct _mongoc_client_encryption_encrypt_text_per_index_opts_t {
bool set;
struct {
bool set;
int32_t value;
} str_max_length;
int32_t str_max_query_length;
int32_t str_min_query_length;
};

struct _mongoc_client_encryption_encrypt_text_opts_t {
bool set;
bool case_sensitive;
bool diacritic_sensitive;

mongoc_client_encryption_encrypt_text_per_index_opts_t substring;
mongoc_client_encryption_encrypt_text_per_index_opts_t prefix;
mongoc_client_encryption_encrypt_text_per_index_opts_t suffix;
};

struct _mongoc_client_encryption_encrypt_opts_t {
bson_value_t keyid;
char *algorithm;
Expand All @@ -473,6 +494,7 @@ struct _mongoc_client_encryption_encrypt_opts_t {
} contention_factor;
char *query_type;
mongoc_client_encryption_encrypt_range_opts_t *range_opts;
mongoc_client_encryption_encrypt_text_opts_t text_opts;
};

mongoc_client_encryption_encrypt_opts_t *
Expand All @@ -481,6 +503,31 @@ mongoc_client_encryption_encrypt_opts_new (void)
return bson_malloc0 (sizeof (mongoc_client_encryption_encrypt_opts_t));
}

mongoc_client_encryption_encrypt_text_per_index_opts_t *
mongoc_client_encryption_encrypt_text_per_index_opts_new (void)
{
return bson_malloc0 (sizeof (mongoc_client_encryption_encrypt_text_per_index_opts_t));
}

void
mongoc_client_encryption_encrypt_text_per_index_opts_destroy (
mongoc_client_encryption_encrypt_text_per_index_opts_t *iopts)
{
bson_free (iopts);
}

mongoc_client_encryption_encrypt_text_opts_t *
mongoc_client_encryption_encrypt_text_opts_new (void)
{
return bson_malloc0 (sizeof (mongoc_client_encryption_encrypt_text_opts_t));
}

void
mongoc_client_encryption_encrypt_text_opts_destroy (mongoc_client_encryption_encrypt_text_opts_t *topts)
{
bson_free (topts);
}

void
mongoc_client_encryption_encrypt_range_opts_destroy (mongoc_client_encryption_encrypt_range_opts_t *range_opts)
{
Expand Down Expand Up @@ -672,6 +719,89 @@ mongoc_client_encryption_encrypt_opts_set_range_opts (mongoc_client_encryption_e
opts->range_opts = copy_range_opts (range_opts);
}

/*--------------------------------------------------------------------------
* Explicit Encryption TextPreview Options
*--------------------------------------------------------------------------
*/
void
mongoc_client_encryption_encrypt_opts_set_text_opts (mongoc_client_encryption_encrypt_opts_t *opts,
const mongoc_client_encryption_encrypt_text_opts_t *text_opts)
{
BSON_ASSERT_PARAM (opts);
opts->text_opts = *text_opts;
opts->text_opts.set = true;
}

void
mongoc_client_encryption_encrypt_text_opts_set_case_sensitive (mongoc_client_encryption_encrypt_text_opts_t *opts,
bool case_sensitive)
{
BSON_ASSERT_PARAM (opts);
opts->case_sensitive = case_sensitive;
}

void
mongoc_client_encryption_encrypt_text_opts_set_diacritic_sensitive (mongoc_client_encryption_encrypt_text_opts_t *opts,
bool diacritic_sensitive)
{
BSON_ASSERT_PARAM (opts);
opts->diacritic_sensitive = diacritic_sensitive;
}

void
mongoc_client_encryption_encrypt_text_per_index_opts_set_str_max_length (
mongoc_client_encryption_encrypt_text_per_index_opts_t *opts, int32_t str_max_length)
{
BSON_ASSERT_PARAM (opts);
opts->str_max_length.set = true;
opts->str_max_length.value = str_max_length;
}

void
mongoc_client_encryption_encrypt_text_per_index_opts_set_str_max_query_length (
mongoc_client_encryption_encrypt_text_per_index_opts_t *opts, int32_t str_max_query_length)
{
BSON_ASSERT_PARAM (opts);
opts->str_max_query_length = str_max_query_length;
}

void
mongoc_client_encryption_encrypt_text_per_index_opts_set_str_min_query_length (
mongoc_client_encryption_encrypt_text_per_index_opts_t *opts, int32_t str_min_query_length)
{
BSON_ASSERT_PARAM (opts);
opts->str_min_query_length = str_min_query_length;
}

void
mongoc_client_encryption_encrypt_text_opts_set_prefix (
mongoc_client_encryption_encrypt_text_opts_t *opts,
mongoc_client_encryption_encrypt_text_per_index_opts_t *per_index_opts)
{
BSON_ASSERT_PARAM (opts);
opts->prefix = *per_index_opts;
opts->prefix.set = true;
}

void
mongoc_client_encryption_encrypt_text_opts_set_suffix (
mongoc_client_encryption_encrypt_text_opts_t *opts,
mongoc_client_encryption_encrypt_text_per_index_opts_t *per_index_opts)
{
BSON_ASSERT_PARAM (opts);
opts->suffix = *per_index_opts;
opts->suffix.set = true;
}

void
mongoc_client_encryption_encrypt_text_opts_set_substring (
mongoc_client_encryption_encrypt_text_opts_t *opts,
mongoc_client_encryption_encrypt_text_per_index_opts_t *per_index_opts)
{
BSON_ASSERT_PARAM (opts);
opts->substring = *per_index_opts;
opts->substring.set = true;
}
/*--------------------------------------------------------------------------
* RewrapManyDataKeyResult.
*--------------------------------------------------------------------------
Expand Down Expand Up @@ -1039,6 +1169,46 @@ append_bson_range_opts (bson_t *bson_range_opts, const mongoc_client_encryption_
}
}

static void
append_bson_text_per_index_opts (bson_t *out, const mongoc_client_encryption_encrypt_text_per_index_opts_t *opts)
{
BSON_ASSERT_PARAM (out);
if (opts->str_max_length.set) {
BSON_ASSERT (bson_append_int32 (out, "strMaxLength", -1, opts->str_max_length.value));
}
BSON_ASSERT (bson_append_int32 (out, "strMaxQueryLength", -1, opts->str_max_query_length));
BSON_ASSERT (bson_append_int32 (out, "strMinQueryLength", -1, opts->str_min_query_length));
}

static void
append_bson_text_opts (bson_t *bson_text_opts, const mongoc_client_encryption_encrypt_text_opts_t *opts)
{
BSON_ASSERT_PARAM (bson_text_opts);
BSON_ASSERT_PARAM (opts);

BSON_ASSERT (BSON_APPEND_BOOL (bson_text_opts, "caseSensitive", opts->case_sensitive));
BSON_ASSERT (BSON_APPEND_BOOL (bson_text_opts, "diacriticSensitive", opts->diacritic_sensitive));

if (opts->prefix.set) {
bson_t per_index_spec;
BSON_ASSERT (BSON_APPEND_DOCUMENT_BEGIN (bson_text_opts, "prefix", &per_index_spec));
append_bson_text_per_index_opts (&per_index_spec, &opts->prefix);
BSON_ASSERT (bson_append_document_end (bson_text_opts, &per_index_spec));
}
if (opts->suffix.set) {
bson_t per_index_spec;
BSON_ASSERT (BSON_APPEND_DOCUMENT_BEGIN (bson_text_opts, "suffix", &per_index_spec));
append_bson_text_per_index_opts (&per_index_spec, &opts->suffix);
BSON_ASSERT (bson_append_document_end (bson_text_opts, &per_index_spec));
}
if (opts->substring.set) {
bson_t per_index_spec;
BSON_ASSERT (BSON_APPEND_DOCUMENT_BEGIN (bson_text_opts, "substring", &per_index_spec));
append_bson_text_per_index_opts (&per_index_spec, &opts->substring);
BSON_ASSERT (bson_append_document_end (bson_text_opts, &per_index_spec));
}
}

/*--------------------------------------------------------------------------
*
* _prep_for_auto_encryption --
Expand Down Expand Up @@ -2642,7 +2812,7 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption,
bson_error_t *error)
{
bool ret = false;
bson_t *range_opts = NULL;
bson_t *range_opts = NULL, *text_opts = NULL;

ENTRY;

Expand All @@ -2668,6 +2838,11 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption,
append_bson_range_opts (range_opts, opts);
}

if (opts->text_opts.set) {
text_opts = bson_new ();
append_bson_text_opts (text_opts, &opts->text_opts);
}

if (!_mongoc_crypt_explicit_encrypt (client_encryption->crypt,
client_encryption->keyvault_coll,
opts->algorithm,
Expand All @@ -2676,6 +2851,7 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption,
opts->query_type,
opts->contention_factor.set ? &opts->contention_factor.value : NULL,
range_opts,
text_opts,
value,
ciphertext,
error)) {
Expand All @@ -2684,6 +2860,7 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption,

ret = true;
fail:
bson_destroy (text_opts);
bson_destroy (range_opts);
RETURN (ret);
}
Expand Down Expand Up @@ -2712,6 +2889,12 @@ mongoc_client_encryption_encrypt_expression (mongoc_client_encryption_t *client_
append_bson_range_opts (range_opts, opts);
}

bson_t *text_opts = NULL;
if (opts->text_opts.set) {
text_opts = bson_new ();
append_bson_text_opts (text_opts, &opts->text_opts);
}

if (!_mongoc_crypt_explicit_encrypt_expression (client_encryption->crypt,
client_encryption->keyvault_coll,
opts->algorithm,
Expand All @@ -2720,6 +2903,7 @@ mongoc_client_encryption_encrypt_expression (mongoc_client_encryption_t *client_
opts->query_type,
opts->contention_factor.set ? &opts->contention_factor.value : NULL,
range_opts,
text_opts,
expr,
expr_out,
error)) {
Expand Down
58 changes: 58 additions & 0 deletions src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,14 @@ struct _mongoc_database_t;
#define MONGOC_ENCRYPT_ALGORITHM_UNINDEXED "Unindexed"
#define MONGOC_ENCRYPT_ALGORITHM_RANGE "Range"
#define MONGOC_ENCRYPT_ALGORITHM_RANGEPREVIEW "RangePreview"
#define MONGOC_ENCRYPT_ALGORITHM_TEXTPREVIEW "TextPreview"

#define MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY "equality"
#define MONGOC_ENCRYPT_QUERY_TYPE_RANGE "range"
#define MONGOC_ENCRYPT_QUERY_TYPE_RANGEPREVIEW "rangePreview"
#define MONGOC_ENCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW "substringPreview"
#define MONGOC_ENCRYPT_QUERY_TYPE_PREFIXPREVIEW "prefixPreview"
#define MONGOC_ENCRYPT_QUERY_TYPE_SUFFIXPREVIEW "suffixPreview"


BSON_BEGIN_DECLS
Expand Down Expand Up @@ -104,6 +108,9 @@ mongoc_auto_encryption_opts_set_kms_credential_provider_callback (mongoc_auto_en
typedef struct _mongoc_client_encryption_opts_t mongoc_client_encryption_opts_t;
typedef struct _mongoc_client_encryption_t mongoc_client_encryption_t;
typedef struct _mongoc_client_encryption_encrypt_range_opts_t mongoc_client_encryption_encrypt_range_opts_t;
typedef struct _mongoc_client_encryption_encrypt_text_per_index_opts_t
mongoc_client_encryption_encrypt_text_per_index_opts_t;
typedef struct _mongoc_client_encryption_encrypt_text_opts_t mongoc_client_encryption_encrypt_text_opts_t;
typedef struct _mongoc_client_encryption_encrypt_opts_t mongoc_client_encryption_encrypt_opts_t;
typedef struct _mongoc_client_encryption_datakey_opts_t mongoc_client_encryption_datakey_opts_t;
typedef struct _mongoc_client_encryption_rewrap_many_datakey_result_t
Expand Down Expand Up @@ -228,6 +235,19 @@ mongoc_client_encryption_decrypt (mongoc_client_encryption_t *client_encryption,
MONGOC_EXPORT (mongoc_client_encryption_encrypt_opts_t *)
mongoc_client_encryption_encrypt_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT;

MONGOC_EXPORT (mongoc_client_encryption_encrypt_text_per_index_opts_t *)
mongoc_client_encryption_encrypt_text_per_index_opts_new (void);

MONGOC_EXPORT (mongoc_client_encryption_encrypt_text_opts_t *)
mongoc_client_encryption_encrypt_text_opts_new (void);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_per_index_opts_destroy (
mongoc_client_encryption_encrypt_text_per_index_opts_t *iopts);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_opts_destroy (mongoc_client_encryption_encrypt_text_opts_t *topts);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_opts_destroy (mongoc_client_encryption_encrypt_opts_t *opts);

Expand Down Expand Up @@ -280,6 +300,44 @@ mongoc_client_encryption_encrypt_range_opts_set_precision (mongoc_client_encrypt
MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_opts_set_range_opts (mongoc_client_encryption_encrypt_opts_t *opts,
const mongoc_client_encryption_encrypt_range_opts_t *range_opts);
MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_opts_set_text_opts (mongoc_client_encryption_encrypt_opts_t *opts,
const mongoc_client_encryption_encrypt_text_opts_t *text_opts);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_opts_set_case_sensitive (mongoc_client_encryption_encrypt_text_opts_t *opts,
bool case_sensitive);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_opts_set_diacritic_sensitive (mongoc_client_encryption_encrypt_text_opts_t *opts,
bool diacritic_sensitive);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_per_index_opts_set_str_max_length (
mongoc_client_encryption_encrypt_text_per_index_opts_t *opts, int32_t str_max_length);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_per_index_opts_set_str_max_query_length (
mongoc_client_encryption_encrypt_text_per_index_opts_t *opts, int32_t str_max_query_length);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_per_index_opts_set_str_min_query_length (
mongoc_client_encryption_encrypt_text_per_index_opts_t *opts, int32_t str_min_query_length);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_opts_set_prefix (
mongoc_client_encryption_encrypt_text_opts_t *opts,
mongoc_client_encryption_encrypt_text_per_index_opts_t *per_index_opts);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_opts_set_suffix (
mongoc_client_encryption_encrypt_text_opts_t *opts,
mongoc_client_encryption_encrypt_text_per_index_opts_t *per_index_opts);

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_text_opts_set_substring (
mongoc_client_encryption_encrypt_text_opts_t *opts,
mongoc_client_encryption_encrypt_text_per_index_opts_t *per_index_opts);

MONGOC_EXPORT (mongoc_client_encryption_datakey_opts_t *)
mongoc_client_encryption_datakey_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT;
Expand Down
Loading