Skip to content

Commit 17827e3

Browse files
authored
CDRIVER-4372 Add FLE 2 API to explicit encryption (#997)
1 parent e8ddd35 commit 17827e3

14 files changed

+805
-11
lines changed

src/libmongoc/doc/mongoc_client_encryption_encrypt.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ Performs explicit encryption.
2020

2121
``ciphertext`` is always initialized (even on failure). Caller must call :symbol:`bson_value_destroy()` to free.
2222

23+
To insert or query with an "Indexed" encrypted payload, use a :symbol:`mongoc_client_t` configured with :symbol:`mongoc_auto_encryption_opts_t`.
24+
The :symbol:`mongoc_auto_encryption_opts_t` may be configured to bypass query analysis with :symbol:`mongoc_auto_encryption_opts_set_bypass_query_analysis`.
25+
The :symbol:`mongoc_auto_encryption_opts_t` must not be configured to bypass automatic encryption with :symbol:`mongoc_auto_encryption_opts_set_bypass_auto_encryption`.
26+
2327
Parameters
2428
----------
2529

src/libmongoc/doc/mongoc_client_encryption_encrypt_opts_set_algorithm.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ Synopsis
1414
1515
#define MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
1616
#define MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
17+
#define MONGOC_ENCRYPT_ALGORITHM_INDEXED "Indexed"
18+
#define MONGOC_ENCRYPT_ALGORITHM_UNINDEXED "Unindexed"
1719
1820
Identifies the algorithm to use for encryption. Valid values of ``algorithm`` are:
1921

2022
* "AEAD_AES_256_CBC_HMAC_SHA_512-Random" for randomized encryption.
2123
* "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" for deterministic (queryable) encryption.
24+
* "Indexed" for indexed encryption.
25+
* "Unindexed" for unindexed encryption.
2226

2327
Parameters
2428
----------
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
:man_page: mongoc_client_encryption_encrypt_opts_set_contention_factor
2+
3+
mongoc_client_encryption_encrypt_opts_set_contention_factor()
4+
=============================================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
MONGOC_EXPORT (void)
12+
mongoc_client_encryption_encrypt_opts_set_contention_factor (
13+
mongoc_client_encryption_encrypt_opts_t *opts, int64_t contention_factor);
14+
15+
Sets a contention factor for explicit encryption.
16+
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed".
17+
It is an error to set the contention factor when algorithm is not "Indexed".
18+
If contention factor is not supplied, it defaults to a value of 0.
19+
20+
Parameters
21+
----------
22+
23+
* ``opts``: A :symbol:`mongoc_client_encryption_encrypt_opts_t`
24+
* ``contention_factor``: A non-negative contention factor.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
:man_page: mongoc_client_encryption_encrypt_opts_set_query_type
2+
3+
mongoc_client_encryption_encrypt_opts_set_query_type()
4+
======================================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
typedef enum { MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY } mongoc_encrypt_query_type_t;
12+
13+
MONGOC_EXPORT (void)
14+
mongoc_client_encryption_encrypt_opts_set_query_type (
15+
mongoc_client_encryption_encrypt_opts_t *opts, mongoc_encrypt_query_type_t query_type);
16+
17+
Sets a query type for explicit encryption.
18+
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed".
19+
It is an error to set the query type when algorithm is not "Indexed".
20+
21+
Parameters
22+
----------
23+
24+
* ``opts``: A :symbol:`mongoc_client_encryption_encrypt_opts_t`
25+
* ``query_type``: A query type to use for explicit encryption.

src/libmongoc/doc/mongoc_client_encryption_encrypt_opts_t.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ Used to set options for :symbol:`mongoc_client_encryption_encrypt()`.
2727
mongoc_client_encryption_encrypt_opts_set_keyid
2828
mongoc_client_encryption_encrypt_opts_set_keyaltname
2929
mongoc_client_encryption_encrypt_opts_set_algorithm
30+
mongoc_client_encryption_encrypt_opts_set_contention_factor
31+
mongoc_client_encryption_encrypt_opts_set_query_type
3032

3133
.. seealso::
3234

src/libmongoc/src/mongoc/mongoc-client-side-encryption.c

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,14 @@ struct _mongoc_client_encryption_encrypt_opts_t {
401401
bson_value_t keyid;
402402
char *algorithm;
403403
char *keyaltname;
404+
struct {
405+
int64_t value;
406+
bool set;
407+
} contention_factor;
408+
struct {
409+
mongoc_encrypt_query_type_t value;
410+
bool set;
411+
} query_type;
404412
};
405413

406414
mongoc_client_encryption_encrypt_opts_t *
@@ -460,6 +468,29 @@ mongoc_client_encryption_encrypt_opts_set_algorithm (
460468
opts->algorithm = bson_strdup (algorithm);
461469
}
462470

471+
void
472+
mongoc_client_encryption_encrypt_opts_set_contention_factor (
473+
mongoc_client_encryption_encrypt_opts_t *opts, int64_t contention_factor)
474+
{
475+
if (!opts) {
476+
return;
477+
}
478+
opts->contention_factor.value = contention_factor;
479+
opts->contention_factor.set = true;
480+
}
481+
482+
void
483+
mongoc_client_encryption_encrypt_opts_set_query_type (
484+
mongoc_client_encryption_encrypt_opts_t *opts,
485+
mongoc_encrypt_query_type_t query_type)
486+
{
487+
if (!opts) {
488+
return;
489+
}
490+
opts->query_type.value = query_type;
491+
opts->query_type.set = true;
492+
}
493+
463494
/*--------------------------------------------------------------------------
464495
* RewrapManyDataKeyResult.
465496
*--------------------------------------------------------------------------
@@ -2011,14 +2042,17 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption,
20112042
GOTO (fail);
20122043
}
20132044

2014-
if (!_mongoc_crypt_explicit_encrypt (client_encryption->crypt,
2015-
client_encryption->keyvault_coll,
2016-
opts->algorithm,
2017-
&opts->keyid,
2018-
opts->keyaltname,
2019-
value,
2020-
ciphertext,
2021-
error)) {
2045+
if (!_mongoc_crypt_explicit_encrypt (
2046+
client_encryption->crypt,
2047+
client_encryption->keyvault_coll,
2048+
opts->algorithm,
2049+
&opts->keyid,
2050+
opts->keyaltname,
2051+
opts->query_type.set ? &opts->query_type.value : NULL,
2052+
opts->contention_factor.set ? &opts->contention_factor.value : NULL,
2053+
value,
2054+
ciphertext,
2055+
error)) {
20222056
GOTO (fail);
20232057
}
20242058

src/libmongoc/src/mongoc/mongoc-client-side-encryption.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ struct _mongoc_client_pool_t;
2929
"AEAD_AES_256_CBC_HMAC_SHA_512-Random"
3030
#define MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC \
3131
"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
32+
#define MONGOC_ENCRYPT_ALGORITHM_INDEXED "Indexed"
33+
#define MONGOC_ENCRYPT_ALGORITHM_UNINDEXED "Unindexed"
3234

3335
BSON_BEGIN_DECLS
3436

@@ -190,6 +192,17 @@ MONGOC_EXPORT (void)
190192
mongoc_client_encryption_encrypt_opts_set_algorithm (
191193
mongoc_client_encryption_encrypt_opts_t *opts, const char *algorithm);
192194

195+
MONGOC_EXPORT (void)
196+
mongoc_client_encryption_encrypt_opts_set_contention_factor (
197+
mongoc_client_encryption_encrypt_opts_t *opts, int64_t contention_factor);
198+
199+
typedef enum { MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY } mongoc_encrypt_query_type_t;
200+
201+
MONGOC_EXPORT (void)
202+
mongoc_client_encryption_encrypt_opts_set_query_type (
203+
mongoc_client_encryption_encrypt_opts_t *opts,
204+
mongoc_encrypt_query_type_t query_type);
205+
193206
MONGOC_EXPORT (mongoc_client_encryption_datakey_opts_t *)
194207
mongoc_client_encryption_datakey_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT;
195208

src/libmongoc/src/mongoc/mongoc-crypt-private.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ Perform explicit encryption.
7979
- exactly one of keyid or keyaltname must be set, the other NULL, or an error is
8080
returned.
8181
- value_out is always initialized.
82+
- query_type may be NULL.
83+
- contention_factor may be NULL.
8284
- may return false and set error.
8385
*/
8486
bool
@@ -87,6 +89,8 @@ _mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt,
8789
const char *algorithm,
8890
const bson_value_t *keyid,
8991
char *keyaltname,
92+
const mongoc_encrypt_query_type_t *query_type,
93+
const int64_t *contention_factor,
9094
const bson_value_t *value_in,
9195
bson_value_t *value_out,
9296
bson_error_t *error);

src/libmongoc/src/mongoc/mongoc-crypt.c

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,8 @@ _mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt,
11341134
const char *algorithm,
11351135
const bson_value_t *keyid,
11361136
char *keyaltname,
1137+
const mongoc_encrypt_query_type_t *query_type,
1138+
const int64_t *contention_factor,
11371139
const bson_value_t *value_in,
11381140
bson_value_t *value_out,
11391141
bson_error_t *error)
@@ -1156,9 +1158,48 @@ _mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt,
11561158
goto fail;
11571159
}
11581160

1159-
if (!mongocrypt_ctx_setopt_algorithm (state_machine->ctx, algorithm, -1)) {
1160-
_ctx_check_error (state_machine->ctx, error, true);
1161-
goto fail;
1161+
if (NULL != algorithm &&
1162+
0 == strcmp (algorithm, MONGOC_ENCRYPT_ALGORITHM_INDEXED)) {
1163+
if (!mongocrypt_ctx_setopt_index_type (state_machine->ctx,
1164+
MONGOCRYPT_INDEX_TYPE_EQUALITY)) {
1165+
_ctx_check_error (state_machine->ctx, error, true);
1166+
goto fail;
1167+
}
1168+
} else if (NULL != algorithm &&
1169+
0 == strcmp (algorithm, MONGOC_ENCRYPT_ALGORITHM_UNINDEXED)) {
1170+
if (!mongocrypt_ctx_setopt_index_type (state_machine->ctx,
1171+
MONGOCRYPT_INDEX_TYPE_NONE)) {
1172+
_ctx_check_error (state_machine->ctx, error, true);
1173+
goto fail;
1174+
}
1175+
} else {
1176+
if (!mongocrypt_ctx_setopt_algorithm (
1177+
state_machine->ctx, algorithm, -1)) {
1178+
_ctx_check_error (state_machine->ctx, error, true);
1179+
goto fail;
1180+
}
1181+
}
1182+
1183+
if (query_type != NULL) {
1184+
mongocrypt_query_type_t converted;
1185+
1186+
switch (*query_type) {
1187+
case MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY:
1188+
converted = MONGOCRYPT_QUERY_TYPE_EQUALITY;
1189+
break;
1190+
}
1191+
if (!mongocrypt_ctx_setopt_query_type (state_machine->ctx, converted)) {
1192+
_ctx_check_error (state_machine->ctx, error, true);
1193+
goto fail;
1194+
}
1195+
}
1196+
1197+
if (contention_factor != NULL) {
1198+
if (!mongocrypt_ctx_setopt_contention_factor (state_machine->ctx,
1199+
*contention_factor)) {
1200+
_ctx_check_error (state_machine->ctx, error, true);
1201+
goto fail;
1202+
}
11621203
}
11631204

11641205
if (keyaltname) {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"fields": [
3+
{
4+
"keyId": {
5+
"$binary": {
6+
"base64": "EjRWeBI0mHYSNBI0VniQEg==",
7+
"subType": "04"
8+
}
9+
},
10+
"path": "encryptedIndexed",
11+
"bsonType": "string",
12+
"queries": {
13+
"queryType": "equality",
14+
"contention": {
15+
"$numberLong": "0"
16+
}
17+
}
18+
},
19+
{
20+
"keyId": {
21+
"$binary": {
22+
"base64": "q83vqxI0mHYSNBI0VniQEg==",
23+
"subType": "04"
24+
}
25+
},
26+
"path": "encryptedUnindexed",
27+
"bsonType": "string"
28+
}
29+
]
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"_id": {
3+
"$binary": {
4+
"base64": "EjRWeBI0mHYSNBI0VniQEg==",
5+
"subType": "04"
6+
}
7+
},
8+
"keyMaterial": {
9+
"$binary": {
10+
"base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==",
11+
"subType": "00"
12+
}
13+
},
14+
"creationDate": {
15+
"$date": {
16+
"$numberLong": "1648914851981"
17+
}
18+
},
19+
"updateDate": {
20+
"$date": {
21+
"$numberLong": "1648914851981"
22+
}
23+
},
24+
"status": {
25+
"$numberInt": "0"
26+
},
27+
"masterKey": {
28+
"provider": "local"
29+
}
30+
}

src/libmongoc/tests/test-libmongoc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2604,6 +2604,8 @@ WIRE_VERSION_CHECKS (9)
26042604
WIRE_VERSION_CHECKS (13)
26052605
/* wire version 14 begins with the 5.1 prerelease. */
26062606
WIRE_VERSION_CHECKS (14)
2607+
/* wire version 17 begins with the 6.0 release. */
2608+
WIRE_VERSION_CHECKS (17)
26072609

26082610
int
26092611
test_framework_skip_if_no_dual_ip_hostname (void)

src/libmongoc/tests/test-libmongoc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ WIRE_VERSION_CHECK_DECLS (9)
199199
WIRE_VERSION_CHECK_DECLS (13)
200200
/* wire version 14 begins with the 5.1 prerelease. */
201201
WIRE_VERSION_CHECK_DECLS (14)
202+
/* wire version 17 begins with the 6.0 release. */
203+
WIRE_VERSION_CHECK_DECLS (17)
202204

203205
#undef WIRE_VERSION_CHECK_DECLS
204206

0 commit comments

Comments
 (0)