Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion .evergreen/scripts/compile-libmongocrypt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ compile_libmongocrypt() {
# `src/kms-message`.
#
# Run `.evergreen/scripts/kms-divergence-check.sh` to ensure that there is no divergence in the copied files.
declare -r version="1.13.0"
declare -r version="1.15.1"

git clone -q --depth=1 https://github.com/mongodb/libmongocrypt --branch "${version:?}" || return

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.1)
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.1 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
248 changes: 247 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 @@ -462,6 +463,26 @@ struct _mongoc_client_encryption_encrypt_range_opts_t {
} precision;
};

typedef struct {
bool set;
int32_t value;
} mc_optional_int32_t;

struct _encrypt_text_per_index_opts_t {
mc_optional_int32_t str_max_length;
mc_optional_int32_t str_max_query_length;
mc_optional_int32_t str_min_query_length;
};

struct _mongoc_encrypt_text_opts_t {
bool case_sensitive;
bool diacritic_sensitive;

mongoc_encrypt_text_substring_opts_t *substring;
mongoc_encrypt_text_prefix_opts_t *prefix;
mongoc_encrypt_text_suffix_opts_t *suffix;
};

struct _mongoc_client_encryption_encrypt_opts_t {
bson_value_t keyid;
char *algorithm;
Expand All @@ -472,6 +493,7 @@ struct _mongoc_client_encryption_encrypt_opts_t {
} contention_factor;
char *query_type;
mongoc_client_encryption_encrypt_range_opts_t *range_opts;
mongoc_encrypt_text_opts_t *text_opts;
};

mongoc_client_encryption_encrypt_opts_t *
Expand All @@ -480,6 +502,143 @@ mongoc_client_encryption_encrypt_opts_new(void)
return bson_malloc0(sizeof(mongoc_client_encryption_encrypt_opts_t));
}

mongoc_encrypt_text_prefix_opts_t *
mongoc_encrypt_text_prefix_opts_new(void)
{
return bson_malloc0(sizeof(mongoc_encrypt_text_prefix_opts_t));
}

void
mongoc_encrypt_text_prefix_opts_destroy(mongoc_encrypt_text_prefix_opts_t *opts)
{
bson_free(opts);
}

void
mongoc_encrypt_text_prefix_opts_set_str_max_query_length(mongoc_encrypt_text_prefix_opts_t *opts, int32_t val)
{
BSON_ASSERT_PARAM(opts);
opts->str_max_query_length.set = true;
opts->str_max_query_length.value = val;
}

void
mongoc_encrypt_text_prefix_opts_set_str_min_query_length(mongoc_encrypt_text_prefix_opts_t *opts, int32_t val)
{
BSON_ASSERT_PARAM(opts);
opts->str_min_query_length.set = true;
opts->str_min_query_length.value = val;
}

// Suffix opts
mongoc_encrypt_text_suffix_opts_t *
mongoc_encrypt_text_suffix_opts_new(void)
{
return bson_malloc0(sizeof(mongoc_encrypt_text_suffix_opts_t));
}

void
mongoc_encrypt_text_suffix_opts_destroy(mongoc_encrypt_text_suffix_opts_t *opts)
{
bson_free(opts);
}

void
mongoc_encrypt_text_suffix_opts_set_str_max_query_length(mongoc_encrypt_text_suffix_opts_t *opts, int32_t val)
{
BSON_ASSERT_PARAM(opts);
opts->str_max_query_length.set = true;
opts->str_max_query_length.value = val;
}

void
mongoc_encrypt_text_suffix_opts_set_str_min_query_length(mongoc_encrypt_text_suffix_opts_t *opts, int32_t val)
{
BSON_ASSERT_PARAM(opts);
opts->str_min_query_length.set = true;
opts->str_min_query_length.value = val;
}

// Substring opts
mongoc_encrypt_text_substring_opts_t *
mongoc_encrypt_text_substring_opts_new(void)
{
return bson_malloc0(sizeof(mongoc_encrypt_text_substring_opts_t));
}

void
mongoc_encrypt_text_substring_opts_destroy(mongoc_encrypt_text_substring_opts_t *opts)
{
bson_free(opts);
}

void
mongoc_encrypt_text_substring_opts_set_str_max_length(mongoc_encrypt_text_substring_opts_t *opts, int32_t val)
{
BSON_ASSERT_PARAM(opts);
opts->str_max_length.set = true;
opts->str_max_length.value = val;
}

void
mongoc_encrypt_text_substring_opts_set_str_max_query_length(mongoc_encrypt_text_substring_opts_t *opts, int32_t val)
{
BSON_ASSERT_PARAM(opts);
opts->str_max_query_length.set = true;
opts->str_max_query_length.value = val;
}

void
mongoc_encrypt_text_substring_opts_set_str_min_query_length(mongoc_encrypt_text_substring_opts_t *opts, int32_t val)
{
BSON_ASSERT_PARAM(opts);
opts->str_min_query_length.set = true;
opts->str_min_query_length.value = val;
}

// Setters for text opts
void
mongoc_encrypt_text_opts_set_prefix(mongoc_encrypt_text_opts_t *opts, mongoc_encrypt_text_prefix_opts_t *popts)
{
BSON_ASSERT_PARAM(opts);
BSON_ASSERT_PARAM(popts);
opts->prefix = mongoc_encrypt_text_prefix_opts_new();
*opts->prefix = *popts;
}

void
mongoc_encrypt_text_opts_set_suffix(mongoc_encrypt_text_opts_t *opts, mongoc_encrypt_text_suffix_opts_t *sopts)
{
BSON_ASSERT_PARAM(opts);
BSON_ASSERT_PARAM(sopts);
opts->suffix = mongoc_encrypt_text_suffix_opts_new();
*opts->suffix = *sopts;
}

void
mongoc_encrypt_text_opts_set_substring(mongoc_encrypt_text_opts_t *opts, mongoc_encrypt_text_substring_opts_t *ssopts)
{
BSON_ASSERT_PARAM(opts);
BSON_ASSERT_PARAM(ssopts);
opts->substring = mongoc_encrypt_text_substring_opts_new();
*opts->substring = *ssopts;
}

mongoc_encrypt_text_opts_t *
mongoc_encrypt_text_opts_new(void)
{
return bson_malloc0(sizeof(mongoc_encrypt_text_opts_t));
}

void
mongoc_encrypt_text_opts_destroy(mongoc_encrypt_text_opts_t *topts)
{
mongoc_encrypt_text_prefix_opts_destroy(topts->prefix);
mongoc_encrypt_text_suffix_opts_destroy(topts->suffix);
mongoc_encrypt_text_substring_opts_destroy(topts->substring);
bson_free(topts);
}

void
mongoc_client_encryption_encrypt_range_opts_destroy(mongoc_client_encryption_encrypt_range_opts_t *range_opts)
{
Expand All @@ -503,6 +662,7 @@ mongoc_client_encryption_encrypt_opts_destroy(mongoc_client_encryption_encrypt_o
return;
}
mongoc_client_encryption_encrypt_range_opts_destroy(opts->range_opts);
mongoc_encrypt_text_opts_destroy(opts->text_opts);
bson_value_destroy(&opts->keyid);
bson_free(opts->algorithm);
bson_free(opts->keyaltname);
Expand Down Expand Up @@ -671,6 +831,34 @@ mongoc_client_encryption_encrypt_opts_set_range_opts(mongoc_client_encryption_en
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_encrypt_text_opts_t *text_opts)
{
BSON_ASSERT_PARAM(opts);
opts->text_opts = mongoc_encrypt_text_opts_new();
*opts->text_opts = *text_opts;
}

void
mongoc_client_encryption_encrypt_text_opts_set_case_sensitive(mongoc_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_encrypt_text_opts_t *opts,
bool diacritic_sensitive)
{
BSON_ASSERT_PARAM(opts);
opts->diacritic_sensitive = diacritic_sensitive;
}

/*--------------------------------------------------------------------------
* RewrapManyDataKeyResult.
*--------------------------------------------------------------------------
Expand Down Expand Up @@ -1038,6 +1226,50 @@ append_bson_range_opts(bson_t *bson_range_opts, const mongoc_client_encryption_e
}
}

static void
append_bson_text_per_index_opts(bson_t *out, const struct _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));
}
if (opts->str_max_query_length.set) {
BSON_ASSERT(bson_append_int32(out, "strMaxQueryLength", -1, opts->str_max_query_length.value));
}
if (opts->str_min_query_length.set) {
BSON_ASSERT(bson_append_int32(out, "strMinQueryLength", -1, opts->str_min_query_length.value));
}
}

static void
append_bson_text_opts(bson_t *bson_text_opts, const mongoc_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) {
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) {
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) {
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 @@ -2641,7 +2873,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 @@ -2667,6 +2899,11 @@ mongoc_client_encryption_encrypt(mongoc_client_encryption_t *client_encryption,
append_bson_range_opts(range_opts, opts);
}

if (opts->text_opts) {
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 @@ -2675,6 +2912,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 @@ -2683,6 +2921,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 @@ -2711,6 +2950,12 @@ mongoc_client_encryption_encrypt_expression(mongoc_client_encryption_t *client_e
append_bson_range_opts(range_opts, opts);
}

bson_t *text_opts = NULL;
if (opts->text_opts) {
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 @@ -2719,6 +2964,7 @@ mongoc_client_encryption_encrypt_expression(mongoc_client_encryption_t *client_e
opts->query_type,
opts->contention_factor.set ? &opts->contention_factor.value : NULL,
range_opts,
text_opts,
expr,
expr_out,
error)) {
Expand Down
Loading