Skip to content

Commit b09fe5d

Browse files
authored
RUST-1605 Update to use libmongocrypt fle2v2 (#863)
1 parent 2c17437 commit b09fe5d

File tree

130 files changed

+1074
-3137
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+1074
-3137
lines changed

.evergreen/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,6 +1983,7 @@ buildvariants:
19831983
os:
19841984
- ubuntu-20.04
19851985
mongodb-version:
1986+
- "latest"
19861987
- "rapid"
19871988
- "6.0"
19881989
topology:

src/client/csfle.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ impl ClientState {
9797
}
9898

9999
fn make_crypt(opts: &AutoEncryptionOptions) -> Result<Crypt> {
100-
let mut builder = Crypt::builder().kms_providers(&opts.kms_providers.credentials_doc()?)?;
100+
let mut builder = Crypt::builder()
101+
.kms_providers(&opts.kms_providers.credentials_doc()?)?
102+
.fle2v2(true)?;
101103
if let Some(m) = &opts.schema_map {
102104
builder = builder.schema_map(&bson::to_document(m)?)?;
103105
}
@@ -204,7 +206,7 @@ pub(crate) fn aux_collections(
204206
enc_fields: &bson::Document,
205207
) -> Result<Vec<Namespace>> {
206208
let mut out = vec![];
207-
for &key in &["esc", "ecc", "ecoc"] {
209+
for &key in &["esc", "ecoc"] {
208210
let coll = match enc_fields.get_str(format!("{}Collection", key)) {
209211
Ok(s) => s.to_string(),
210212
Err(_) => format!("enxcol_.{}.{}", base_ns.coll, key),

src/client/csfle/client_encryption.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl ClientEncryption {
7474
let crypt = Crypt::builder()
7575
.kms_providers(&kms_providers.credentials_doc()?)?
7676
.use_need_kms_credentials_state()
77+
.fle2v2(true)?
7778
.build()?;
7879
let exec = CryptExecutor::new_explicit(
7980
key_vault_client.weak(),

src/client/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,29 @@ impl Client {
565565
&self.inner.topology
566566
}
567567

568+
#[cfg(feature = "in-use-encryption-unstable")]
569+
pub(crate) async fn primary_description(&self) -> Option<crate::sdam::ServerDescription> {
570+
let start_time = Instant::now();
571+
let timeout = self
572+
.inner
573+
.options
574+
.server_selection_timeout
575+
.unwrap_or(DEFAULT_SERVER_SELECTION_TIMEOUT);
576+
let mut watcher = self.inner.topology.watch();
577+
loop {
578+
let topology = watcher.observe_latest();
579+
if let Some(desc) = topology.description.primary() {
580+
return Some(desc.clone());
581+
}
582+
if !watcher
583+
.wait_for_update(timeout - start_time.elapsed())
584+
.await
585+
{
586+
return None;
587+
}
588+
}
589+
}
590+
568591
#[cfg(feature = "in-use-encryption-unstable")]
569592
pub(crate) fn weak(&self) -> WeakClient {
570593
WeakClient {

src/db/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,22 @@ impl Database {
379379
Some(f) => f,
380380
None => return Ok(()),
381381
};
382+
let max_wire = match self.client().primary_description().await {
383+
Some(p) => p.max_wire_version()?,
384+
None => None,
385+
};
386+
const SERVER_7_0_0_WIRE_VERSION: i32 = 21;
387+
match max_wire {
388+
Some(v) if v >= SERVER_7_0_0_WIRE_VERSION => (),
389+
_ => {
390+
return Err(ErrorKind::IncompatibleServer {
391+
message: "Driver support of Queryable Encryption is incompatible with server. \
392+
Upgrade server to use Queryable Encryption."
393+
.to_string(),
394+
}
395+
.into())
396+
}
397+
}
382398
for ns in crate::client::csfle::aux_collections(base_ns, enc_fields)? {
383399
let mut sub_opts = opts.clone();
384400
sub_opts.clustered_index = Some(self::options::ClusteredIndex {

src/sdam/description/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515

1616
const DRIVER_MIN_DB_VERSION: &str = "3.6";
1717
const DRIVER_MIN_WIRE_VERSION: i32 = 6;
18-
const DRIVER_MAX_WIRE_VERSION: i32 = 17;
18+
const DRIVER_MAX_WIRE_VERSION: i32 = 21;
1919

2020
/// Enum representing the possible types of servers that the driver can connect to.
2121
#[derive(Debug, Deserialize, Clone, Copy, Eq, PartialEq, Serialize)]

src/sdam/description/topology/server_selection/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl TopologyDescription {
186186
.filter(move |server| types.contains(&server.server_type))
187187
}
188188

189-
#[cfg(test)]
189+
#[cfg(any(test, feature = "in-use-encryption-unstable"))]
190190
pub(crate) fn primary(&self) -> Option<&ServerDescription> {
191191
self.servers_with_type(&[ServerType::RsPrimary]).next()
192192
}

src/test/csfle.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ use super::{
6868
TestClient,
6969
CLIENT_OPTIONS,
7070
LOCK,
71+
SERVERLESS,
7172
};
7273

7374
type Result<T> = anyhow::Result<T>;
@@ -2062,15 +2063,34 @@ async fn kms_tls_options() -> Result<()> {
20622063
Ok(())
20632064
}
20642065

2066+
async fn fle2v2_ok(name: &str) -> bool {
2067+
if *SERVERLESS {
2068+
log_uncaptured(format!("Skipping {}: not supported on serverless", name));
2069+
return false;
2070+
}
2071+
let setup_client = Client::test_builder().build().await;
2072+
if setup_client.server_version_lt(7, 0) {
2073+
log_uncaptured(format!("Skipping {}: not supported on server < 7.0", name));
2074+
return false;
2075+
}
2076+
if setup_client.is_standalone() {
2077+
log_uncaptured(format!("Skipping {}: not supported on standalone", name));
2078+
return false;
2079+
}
2080+
true
2081+
}
2082+
20652083
// Prose test 12. Explicit Encryption (Case 1: can insert encrypted indexed and find)
20662084
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
20672085
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
20682086
async fn explicit_encryption_case_1() -> Result<()> {
20692087
if !check_env("explicit_encryption_case_1", false) {
20702088
return Ok(());
20712089
}
2090+
if !fle2v2_ok("explicit_encryption_case_1").await {
2091+
return Ok(());
2092+
}
20722093
let _guard = LOCK.run_exclusively().await;
2073-
20742094
let testdata = match explicit_encryption_setup().await? {
20752095
Some(t) => t,
20762096
None => return Ok(()),
@@ -2127,6 +2147,9 @@ async fn explicit_encryption_case_2() -> Result<()> {
21272147
if !check_env("explicit_encryption_case_2", false) {
21282148
return Ok(());
21292149
}
2150+
if !fle2v2_ok("explicit_encryption_case_2").await {
2151+
return Ok(());
2152+
}
21302153
let _guard = LOCK.run_exclusively().await;
21312154

21322155
let testdata = match explicit_encryption_setup().await? {
@@ -2206,6 +2229,9 @@ async fn explicit_encryption_case_3() -> Result<()> {
22062229
if !check_env("explicit_encryption_case_3", false) {
22072230
return Ok(());
22082231
}
2232+
if !fle2v2_ok("explicit_encryption_case_3").await {
2233+
return Ok(());
2234+
}
22092235
let _guard = LOCK.run_exclusively().await;
22102236

22112237
let testdata = match explicit_encryption_setup().await? {
@@ -2254,6 +2280,9 @@ async fn explicit_encryption_case_4() -> Result<()> {
22542280
if !check_env("explicit_encryption_case_4", false) {
22552281
return Ok(());
22562282
}
2283+
if !fle2v2_ok("explicit_encryption_case_4").await {
2284+
return Ok(());
2285+
}
22572286
let _guard = LOCK.run_exclusively().await;
22582287

22592288
let testdata = match explicit_encryption_setup().await? {
@@ -2288,6 +2317,9 @@ async fn explicit_encryption_case_5() -> Result<()> {
22882317
if !check_env("explicit_encryption_case_5", false) {
22892318
return Ok(());
22902319
}
2320+
if !fle2v2_ok("explicit_encryption_case_5").await {
2321+
return Ok(());
2322+
}
22912323
let _guard = LOCK.run_exclusively().await;
22922324

22932325
let testdata = match explicit_encryption_setup().await? {
@@ -2904,6 +2936,9 @@ async fn auto_encryption_keys(master_key: MasterKey) -> Result<()> {
29042936
if !check_env("custom_key_material", false) {
29052937
return Ok(());
29062938
}
2939+
if !fle2v2_ok("auto_encryption_keys").await {
2940+
return Ok(());
2941+
}
29072942
let _guard = LOCK.run_exclusively().await;
29082943

29092944
let client = Client::test_builder().build().await;
@@ -3022,6 +3057,9 @@ async fn auto_encryption_keys(master_key: MasterKey) -> Result<()> {
30223057
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
30233058
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
30243059
async fn range_explicit_encryption() -> Result<()> {
3060+
if !fle2v2_ok("range_explicit_encryption").await {
3061+
return Ok(());
3062+
}
30253063
let client = TestClient::new().await;
30263064
if client.server_version_lt(6, 2) || client.is_standalone() {
30273065
log_uncaptured("Skipping range_explicit_encryption due to unsupported topology");
@@ -3410,8 +3448,8 @@ async fn fle2_example() -> Result<()> {
34103448

34113449
// FLE 2 is not supported on Standalone topology.
34123450
let test_client = Client::test_builder().build().await;
3413-
if test_client.server_version_lt(6, 0) {
3414-
log_uncaptured("skipping fle2 example: server below 6.0");
3451+
if test_client.server_version_lt(7, 0) {
3452+
log_uncaptured("skipping fle2 example: server below 7.0");
34153453
return Ok(());
34163454
}
34173455
if test_client.is_standalone() {

src/test/spec/json/client-side-encryption/README.rst

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,7 +1679,14 @@ Expect no error on construction.
16791679
12. Explicit Encryption
16801680
~~~~~~~~~~~~~~~~~~~~~~~
16811681

1682-
The Explicit Encryption tests require MongoDB server 6.0+. The tests must not run against a standalone.
1682+
The Explicit Encryption tests require MongoDB server 7.0+. The tests must not run against a standalone.
1683+
1684+
.. note::
1685+
MongoDB Server 7.0 introduced a backwards breaking change to the Queryable Encryption (QE) protocol: QEv2.
1686+
libmongocrypt 1.8.0 is configured to use the QEv2 protocol.
1687+
1688+
.. note::
1689+
Skip this test on Serverless until MongoDB Serverless enables the QEv2 protocol. Refer: `DRIVERS-2589 <https://jira.mongodb.org/browse/DRIVERS-2589>`_
16831690

16841691
Before running each of the following test cases, perform the following Test Setup.
16851692

@@ -2495,7 +2502,14 @@ The following tests that a mongocryptd client is not created when shared library
24952502
21. Automatic Data Encryption Keys
24962503
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24972504

2498-
The Automatic Data Encryption Keys tests require MongoDB server 6.0+. The tests must not run against a standalone.
2505+
The Automatic Data Encryption Keys tests require MongoDB server 7.0+. The tests must not run against a standalone.
2506+
2507+
.. note::
2508+
MongoDB Server 7.0 introduced a backwards breaking change to the Queryable Encryption (QE) protocol: QEv2.
2509+
libmongocrypt 1.8.0 is configured to use the QEv2 protocol.
2510+
2511+
.. note::
2512+
Skip this test on Serverless until MongoDB Serverless enables the QEv2 protocol. Refer: `DRIVERS-2589 <https://jira.mongodb.org/browse/DRIVERS-2589>`_
24992513

25002514
For each of the following test cases, assume `DB` is a valid open database
25012515
handle, and assume a ClientEncryption_ object `CE` created using the following
@@ -2644,7 +2658,14 @@ with encrypted value.
26442658

26452659
22. Range Explicit Encryption
26462660
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2647-
The Range Explicit Encryption tests require MongoDB server 6.2+. The tests must not run against a standalone.
2661+
The Range Explicit Encryption tests require MongoDB server 7.0+. The tests must not run against a standalone.
2662+
2663+
.. note::
2664+
MongoDB Server 7.0 introduced a backwards breaking change to the Queryable Encryption (QE) protocol: QEv2.
2665+
libmongocrypt 1.8.0 is configured to use the QEv2 protocol.
2666+
2667+
.. note::
2668+
Skip this test on Serverless until MongoDB Serverless enables the QEv2 protocol. Refer: `DRIVERS-2589 <https://jira.mongodb.org/browse/DRIVERS-2589>`_
26482669

26492670
Each of the following test cases must pass for each of the supported types (``DecimalNoPrecision``, ``DecimalPrecision``, ``DoublePrecision``, ``DoubleNoPrecision``, ``Date``, ``Int``, and ``Long``), unless it is stated the type should be skipped.
26502671

@@ -2654,7 +2675,7 @@ Before running each of the following test cases, perform the following Test Setu
26542675

26552676
Test Setup
26562677
``````````
2657-
Load the file for the specific data type being tested ``encryptedFields-<type>.json``. For example, for ``Int`` load `range-encryptedFields-Int.json <https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/etc/data/range-encryptedFields-Int.json>`_ as ``encryptedFields``.
2678+
Load the file for the specific data type being tested ``range-encryptedFields-<type>.json``. For example, for ``Int`` load `range-encryptedFields-Int.json <https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/etc/data/range-encryptedFields-Int.json>`_ as ``encryptedFields``.
26582679

26592680
Load the file `key1-document.json <https://github.com/mongodb/specifications/tree/master/source/client-side-encryption/etc/data/keys/key1-document.json>`_ as ``key1Document``.
26602681

0 commit comments

Comments
 (0)