Skip to content

Commit 7a6b636

Browse files
galon1kevinAlbs
andauthored
CDRIVER-4394 Add explicit encryption support and tests for range indexes (#1152)
* require libmongocrypt 1.7.0-alpha1 Co-authored-by: Kevin Albertson <[email protected]>
1 parent fa7d499 commit 7a6b636

34 files changed

+1763
-56
lines changed

.evergreen/compile-test-azurekms.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ ROOT=$(pwd)
88
INSTALL_DIR=$ROOT/install
99
. .evergreen/find-cmake.sh
1010
echo "Installing libmongocrypt ... begin"
11-
git clone https://github.com/mongodb/libmongocrypt --branch 1.6.0
11+
# TODO(CDRIVER-4394) update to use libmongocrypt 1.7.0 once there is a stable 1.7.0 release.
12+
git clone https://github.com/mongodb/libmongocrypt --branch 1.7.0-alpha1
1213
$CMAKE -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \
1314
-DBUILD_TESTING=OFF \
1415
"-H$ROOT/libmongocrypt" \

.evergreen/compile-unix.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ pkg-config --modversion libssl || true
229229

230230
if [ "$COMPILE_LIBMONGOCRYPT" = "ON" ]; then
231231
# Build libmongocrypt, using the previously fetched installed source.
232-
git clone https://github.com/mongodb/libmongocrypt --branch 1.6.0
232+
# TODO(CDRIVER-4394) update to use libmongocrypt 1.7.0 once there is a stable 1.7.0 release.
233+
git clone https://github.com/mongodb/libmongocrypt --branch 1.7.0-alpha1
233234

234235
mkdir libmongocrypt/cmake-build
235236
cd libmongocrypt/cmake-build

.evergreen/compile-windows.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ fi
120120

121121
if [ "$COMPILE_LIBMONGOCRYPT" = "ON" ]; then
122122
# Build libmongocrypt, using the previously fetched installed source.
123-
git clone https://github.com/mongodb/libmongocrypt --branch 1.6.0
123+
# TODO(CDRIVER-4394) update to use libmongocrypt 1.7.0 once there is a stable 1.7.0 release.
124+
git clone https://github.com/mongodb/libmongocrypt --branch 1.7.0-alpha1
124125
mkdir libmongocrypt/cmake-build
125126
cd libmongocrypt/cmake-build
126127
"$CMAKE" -G "$CC" "-DCMAKE_PREFIX_PATH=${INSTALL_DIR}/lib/cmake" -DENABLE_SHARED_BSON=ON -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" ../

src/libmongoc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ elseif (NOT ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL OFF)
441441
find_package (mongocrypt QUIET)
442442
endif ()
443443

444+
# TODO(CDRIVER-4394) update to use libmongocrypt 1.7.0 once there is a stable 1.7.0 release.
444445
if (mongocrypt_FOUND AND "${mongocrypt_VERSION}" VERSION_LESS 1.6.0)
445446
message ("-- libmongocrypt found at ${mongocrypt_DIR}")
446447
message ("-- libmongocrypt version ${mongocrypt_VERSION} found")

src/libmongoc/doc/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ API Reference
1717
mongoc_client_encryption_datakey_opts_t
1818
mongoc_client_encryption_rewrap_many_datakey_result_t
1919
mongoc_client_encryption_encrypt_opts_t
20+
mongoc_client_encryption_encrypt_range_opts_t
2021
mongoc_client_encryption_opts_t
2122
mongoc_client_pool_t
2223
mongoc_client_session_t

src/libmongoc/doc/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@
7171
7272
This API |qenc:is-experimental|
7373
74+
.. |qenc:range-is-experimental| replace::
75+
76+
Range algorithm is experimental only and not intended for public use. It is subject to breaking changes.
77+
7478
'''
7579

7680

src/libmongoc/doc/mongoc_client_encryption_encrypt.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,22 @@ 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
23+
To insert or query with an "Indexed" or "RangePreview" encrypted payload, use a
2424
:symbol:`mongoc_client_t` configured with
2525
:symbol:`mongoc_auto_encryption_opts_t`. The
2626
:symbol:`mongoc_auto_encryption_opts_t` may be configured to bypass query
2727
analysis with :symbol:`mongoc_auto_encryption_opts_set_bypass_query_analysis`.
2828
The :symbol:`mongoc_auto_encryption_opts_t` must not be configured to bypass
2929
automatic encryption with
3030
:symbol:`mongoc_auto_encryption_opts_set_bypass_auto_encryption`. **Note** that
31-
the ``"Indexed"`` payload type |qenc:is-experimental|
31+
the ``"Indexed"`` and ``"RangePreview"`` payload type |qenc:is-experimental|. The |qenc:range-is-experimental|
32+
33+
To insert with a ``RangePreview`` payload
34+
:symbol:`mongoc_client_encryption_encrypt_range_opts_t` must be set in ``opts``.
35+
36+
To query with a ``RangePreview`` payload, use :symbol:`mongoc_client_encryption_encrypt_expression()`
37+
38+
**NOTE** that the |qenc:range-is-experimental|
3239

3340
Parameters
3441
----------
@@ -52,3 +59,4 @@ Returns ``true`` if successful. Returns ``false`` and sets ``error`` otherwise.
5259
5360
| :symbol:`mongoc_client_encryption_decrypt()`
5461
62+
| :symbol:`mongoc_client_encryption_encrypt_expression()`
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
:man_page: mongoc_client_encryption_encrypt_expression
2+
3+
mongoc_client_encryption_encrypt_expression()
4+
=============================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
bool
12+
mongoc_client_encryption_encrypt_expression (
13+
mongoc_client_encryption_t *client_encryption,
14+
const bson_t *expr,
15+
mongoc_client_encryption_encrypt_opts_t *opts,
16+
bson_t *expr_out,
17+
bson_error_t *error);
18+
19+
.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
20+
.. versionadded:: 1.24.0
21+
22+
Encrypts a Match Expression or Aggregate Expression to query a range index.
23+
24+
To query with a ``RangePreview`` encrypted payload, use a
25+
:symbol:`mongoc_client_t` configured with
26+
:symbol:`mongoc_auto_encryption_opts_t`. The
27+
:symbol:`mongoc_auto_encryption_opts_t` may be configured to bypass query
28+
analysis with :symbol:`mongoc_auto_encryption_opts_set_bypass_query_analysis`.
29+
The :symbol:`mongoc_auto_encryption_opts_t` must not be configured to bypass
30+
automatic encryption with
31+
:symbol:`mongoc_auto_encryption_opts_set_bypass_auto_encryption`.
32+
33+
To query with a ``RangePreview`` payload, ``expr`` must be one of the following forms:
34+
35+
#. A Match Expression of the following form:
36+
37+
.. code-block:: javascript
38+
39+
// $gt may also be $gte. $lt may also be $lte.
40+
// Can include one of $gt/$gte/$lt/$lte. It is not required to include both.
41+
{"$and": [{"<field>": {"$gt": "<value1>"}}, {"<field>": {"$lt": "<value2>" }}]}
42+
43+
#. An Aggregation Expression of this form:
44+
45+
.. code-block:: javascript
46+
47+
// $gt may also be $gte. $lt may also be $lte
48+
// Can include one of $gt/$gte/$lt/$lte. It is not required to include both.
49+
{"$and": [{"$gt": ["<fieldpath>", "<value1>"]}, {"$lt": ["<fieldpath>", "<value2>"]}]
50+
51+
Parameters
52+
----------
53+
54+
* ``client_encryption``: A :symbol:`mongoc_client_encryption_t`
55+
* ``expr``: The expression to encrypt.
56+
* ``opts``: A :symbol:`mongoc_client_encryption_encrypt_opts_t`.
57+
* ``expr_out``: A :symbol:`bson_t` for the resulting encrypted expression. ``expr_out`` is always initialized (even on failure). Caller must call :symbol:`bson_destroy()` to free.
58+
* ``error``: A :symbol:`bson_error_t` set on failure.
59+
60+
Returns
61+
-------
62+
63+
Returns ``true`` if successful. Returns ``false`` and sets ``error`` otherwise.
64+
65+
.. seealso::
66+
67+
| :symbol:`mongoc_client_encryption_encrypt_opts_t`
68+
69+
| :symbol:`mongoc_client_enable_auto_encryption()`
70+
71+
| :symbol:`mongoc_client_encryption_decrypt()`
72+

src/libmongoc/doc/mongoc_client_encryption_encrypt_opts_set_algorithm.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Synopsis
1818
#define MONGOC_ENCRYPT_ALGORITHM_INDEXED "Indexed"
1919
// (Experimental: See below)
2020
#define MONGOC_ENCRYPT_ALGORITHM_UNINDEXED "Unindexed"
21+
// (Experimental: See below)
22+
#define MONGOC_ENCRYPT_ALGORITHM_RANGEPREVIEW "RangePreview"
2123
2224
Identifies the algorithm to use for encryption. Valid values of ``algorithm`` are:
2325

@@ -41,6 +43,12 @@ Identifies the algorithm to use for encryption. Valid values of ``algorithm`` ar
4143

4244
.. note:: |qenc:opt-is-experimental|
4345

46+
``"RangePreview"``
47+
48+
for range encryption.
49+
50+
.. note:: The |qenc:range-is-experimental| |qenc:opt-is-experimental|
51+
4452
Parameters
4553
----------
4654

src/libmongoc/doc/mongoc_client_encryption_encrypt_opts_set_contention_factor.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ Synopsis
1616
.. versionadded:: 1.22.0
1717

1818
Sets a contention factor for explicit encryption.
19-
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed".
20-
It is an error to set the contention factor when algorithm is not "Indexed".
19+
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed" or "RangePreview".
20+
It is an error to set the contention factor when algorithm is not "Indexed" or "RangePreview". **Note** that the |qenc:range-is-experimental|
2121
If contention factor is not supplied, it defaults to a value of 0.
2222

2323
Parameters

src/libmongoc/doc/mongoc_client_encryption_encrypt_opts_set_query_type.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Synopsis
99
.. code-block:: c
1010
1111
#define MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY "equality"
12+
#define MONGOC_ENCRYPT_QUERY_TYPE_RANGEPREVIEW "rangePreview"
1213
1314
MONGOC_EXPORT (void)
1415
mongoc_client_encryption_encrypt_opts_set_query_type (
@@ -17,11 +18,11 @@ Synopsis
1718
.. important:: |qenc:api-is-experimental|
1819
.. versionadded:: 1.22.0
1920

20-
Sets a query type for explicit encryption. Currently, the only supported value
21-
for ``query_type`` is ``"equality"``.
21+
Sets a query type for explicit encryption. Currently, the supported values
22+
for ``query_type`` are ``"equality"`` and ``"rangePreview"``. **NOTE** that the |qenc:range-is-experimental|
2223

23-
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed".
24-
It is an error to set the query type when algorithm is not "Indexed".
24+
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed" or "RangePreview".
25+
It is an error to set the query type when algorithm is not "Indexed" or "RangePreview".
2526

2627
Parameters
2728
----------
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
:man_page: mongoc_client_encryption_encrypt_opts_set_range_opts
2+
3+
mongoc_client_encryption_encrypt_opts_set_range_opts()
4+
======================================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
void
12+
mongoc_client_encryption_encrypt_opts_set_range_opts (
13+
mongoc_client_encryption_encrypt_opts_t *opts,
14+
const mongoc_client_encryption_encrypt_range_opts_t *range_opts);
15+
16+
.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
17+
.. versionadded:: 1.24.0
18+
19+
Sets the ``range_opts`` for explicit encryption.
20+
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "RangePreview".
21+
It is an error to set ``range_opts`` when algorithm is not "RangePreview".
22+
23+
Parameters
24+
----------
25+
26+
* ``opts``: A :symbol:`mongoc_client_encryption_encrypt_opts_t`
27+
* ``range_opts``: A :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
28+
29+
.. seealso::
30+
31+
| :symbol:`mongoc_client_encryption_encrypt_range_opts_new`

src/libmongoc/doc/mongoc_client_encryption_encrypt_opts_t.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Used to set options for :symbol:`mongoc_client_encryption_encrypt()`.
2929
mongoc_client_encryption_encrypt_opts_set_algorithm
3030
mongoc_client_encryption_encrypt_opts_set_contention_factor
3131
mongoc_client_encryption_encrypt_opts_set_query_type
32+
mongoc_client_encryption_encrypt_opts_set_range_opts
3233

3334
.. seealso::
3435

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_range_opts_destroy
2+
3+
mongoc_client_encryption_encrypt_range_opts_destroy()
4+
=====================================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
void
12+
mongoc_client_encryption_encrypt_range_opts_destroy (mongoc_client_encryption_encrypt_range_opts_t *range_opts);
13+
14+
.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
15+
.. versionadded:: 1.24.0
16+
17+
Frees resources of a :symbol:`mongoc_client_encryption_encrypt_range_opts_t` created with :symbol:`mongoc_client_encryption_encrypt_range_opts_new()`. Does nothing if ``NULL`` is passed.
18+
19+
Parameters
20+
----------
21+
22+
* ``range_opts``: A :symbol:`mongoc_client_encryption_encrypt_range_opts_t`.
23+
24+
.. seealso::
25+
| :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
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_range_opts_new
2+
3+
mongoc_client_encryption_encrypt_range_opts_new()
4+
=================================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
mongoc_client_encryption_encrypt_range_opts_t *
12+
mongoc_client_encryption_encrypt_range_opts_new (void);
13+
14+
.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
15+
.. versionadded:: 1.24.0
16+
17+
Returns
18+
-------
19+
20+
A new :symbol:`mongoc_client_encryption_encrypt_range_opts_t` that must be freed with :symbol:`mongoc_client_encryption_encrypt_range_opts_destroy()`.
21+
22+
23+
.. seealso::
24+
| :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
25+
| :symbol:`mongoc_client_encryption_encrypt_range_opts_destroy`
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
:man_page: mongoc_client_encryption_encrypt_range_opts_set_min_max
2+
3+
mongoc_client_encryption_encrypt_range_opts_set_min_max()
4+
=========================================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
void
12+
mongoc_client_encryption_encrypt_opts_set_min_max (
13+
mongoc_client_encryption_encrypt_range_opts_t *range_opts,
14+
const bson_value_t *min,
15+
const bson_value_t *max);
16+
17+
.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
18+
.. versionadded:: 1.24.0
19+
20+
Sets the minimum and maximum values of the range for explicit encryption.
21+
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "RangePreview".
22+
It is an error to set minimum and maximum when algorithm is not "RangePreview".
23+
24+
The minimum and maximum must match the values set in the encryptedFields of the destination collection.
25+
It is an error to set a different value.
26+
27+
For double and decimal128 fields, min/max/precision must all be set, or all be unset.
28+
29+
Parameters
30+
----------
31+
32+
* ``range_opts``: A :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
33+
* ``min``: The minimum bson value of the range.
34+
* ``max``: The maximum bson value of the range.
35+
36+
.. seealso::
37+
38+
| :symbol:`mongoc_client_encryption_encrypt_range_opts_set_precision`
39+
| :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
:man_page: mongoc_client_encryption_encrypt_range_opts_set_precision
2+
3+
mongoc_client_encryption_encrypt_range_opts_set_precision()
4+
===========================================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
void
12+
mongoc_client_encryption_encrypt_opts_set_precision (
13+
mongoc_client_encryption_encrypt_range_opts_t *range_opts, int32_t precision);
14+
15+
.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
16+
.. versionadded:: 1.24.0
17+
18+
Sets precision for explicit encryption.
19+
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "RangePreview".
20+
It is an error to set precision when algorithm is not "RangePreview".
21+
22+
Precision can only be set with double or decimal128 fields.
23+
It is an error to set precision if the type of the encryptedFields in the destination collection is not double or decimal128.
24+
25+
For double and decimal128 fields, min/max/precision must all be set, or all be unset.
26+
27+
Precision must match the value set in the encryptedFields of the destination collection.
28+
It is an error to set a different value.
29+
30+
Parameters
31+
----------
32+
33+
* ``range_opts``: A :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
34+
* ``precision``: A non-negative precision.
35+
36+
.. seealso::
37+
38+
| :symbol:`mongoc_client_encryption_encrypt_range_opts_set_min_max`
39+
| :symbol:`mongoc_client_encryption_encrypt_range_opts_t`

0 commit comments

Comments
 (0)