Skip to content

Commit f5073ca

Browse files
[CDRIVER-4414] Get crypt_shared version on a client/encryption object (#1083)
* An API to get the crypt_shared version used for encryption * Test that we bypassSpawn when using crypt_shared * Fix: Don't spawn mongocryptd if we successfully loaded a crypt_shared
1 parent f35c380 commit f5073ca

10 files changed

+174
-8
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
:man_page: mongoc_client_encryption_get_crypt_shared_version
2+
3+
mongoc_client_encryption_get_crypt_shared_version()
4+
===================================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
const char*
12+
mongoc_client_encryption_get_crypt_shared_version (mongoc_client_encryption_t const *enc)
13+
BSON_GNUC_WARN_UNUSED_RESULT;
14+
15+
Obtain the version string of the crypt_shared_ that is loaded for the given
16+
explicit encryption object. If no crypt_shared_ library is loaded, the returned
17+
pointer will be ``NULL``.
18+
19+
Parameters
20+
----------
21+
22+
* ``enc``: A live :symbol:`mongoc_client_encryption_t`
23+
24+
Returns
25+
-------
26+
27+
A pointer to a null-terminated character array string designating the version of
28+
crypt_shared_ that was loaded for ``enc``. If no crypt_shared_ library is
29+
loaded, the returned pointer will be ``NULL``. The pointed-to array must not be
30+
modified or freed. The returned pointer is only valid for the lifetime of
31+
``enc``.
32+
33+
.. _crypt_shared: https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#crypt-shared
34+
35+
.. seealso::
36+
37+
- :symbol:`mongoc_client_get_crypt_shared_version`

src/libmongoc/doc/mongoc_client_encryption_t.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The key vault client, configured via :symbol:`mongoc_client_encryption_opts_set_
3737
mongoc_client_encryption_create_datakey
3838
mongoc_client_encryption_rewrap_many_datakey
3939
mongoc_client_encryption_delete_key
40+
mongoc_client_encryption_get_crypt_shared_version
4041
mongoc_client_encryption_get_key
4142
mongoc_client_encryption_get_keys
4243
mongoc_client_encryption_add_key_alt_name
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
:man_page: mongoc_client_get_crypt_shared_version
2+
3+
mongoc_client_get_crypt_shared_version()
4+
========================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
const char *
12+
mongoc_client_get_crypt_shared_version (const mongoc_client_t *client)
13+
BSON_GNUC_WARN_UNUSED_RESULT;
14+
15+
Obtain the version string of the crypt_shared_ that is loaded for
16+
auto-encryption on the given ``client``. If no crypt_shared_ library is loaded,
17+
the returned pointer will be ``NULL``.
18+
19+
Parameters
20+
----------
21+
22+
* ``client``: A live :symbol:`mongoc_client_t`
23+
24+
Returns
25+
-------
26+
27+
A pointer to a null-terminated character array string designating the version of
28+
crypt_shared_ that was loaded for auto-encryption with ``client``. If no
29+
crypt_shared_ library is loaded, or auto-encryption is not loaded for the given
30+
``client``, the returned pointer will be ``NULL``. The pointed-to array must not
31+
be modified or freed. The returned pointer is only valid for the lifetime of
32+
``client``.
33+
34+
.. _crypt_shared: https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#crypt-shared
35+
36+
.. seealso::
37+
38+
- :symbol:`mongoc_client_encryption_get_crypt_shared_version`

src/libmongoc/doc/mongoc_client_t.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Example
5656
mongoc_client_enable_auto_encryption
5757
mongoc_client_find_databases_with_opts
5858
mongoc_client_get_collection
59+
mongoc_client_get_crypt_shared_version
5960
mongoc_client_get_database
6061
mongoc_client_get_database_names
6162
mongoc_client_get_database_names_with_opts
@@ -91,5 +92,5 @@ Example
9192
mongoc_client_watch
9293
mongoc_client_write_command_with_opts
9394
mongoc_handshake_data_append
94-
95+
9596

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1658,11 +1658,14 @@ _mongoc_cse_client_enable_auto_encryption (mongoc_client_t *client,
16581658
GOTO (fail);
16591659
}
16601660

1661+
const bool have_crypt_shared =
1662+
_mongoc_crypt_get_crypt_shared_version (client->topology->crypt) != NULL;
1663+
16611664
client->topology->bypass_auto_encryption = opts->bypass_auto_encryption;
16621665
client->topology->bypass_query_analysis = opts->bypass_query_analysis;
16631666

16641667
if (!client->topology->bypass_auto_encryption &&
1665-
!client->topology->bypass_query_analysis) {
1668+
!client->topology->bypass_query_analysis && !have_crypt_shared) {
16661669
if (!client->topology->mongocryptd_bypass_spawn) {
16671670
if (!_spawn_mongocryptd (client->topology->mongocryptd_spawn_path,
16681671
client->topology->mongocryptd_spawn_args,
@@ -2670,3 +2673,30 @@ _mongoc_cse_is_enabled (mongoc_client_t *client)
26702673
}
26712674

26722675
#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
2676+
2677+
2678+
const char *
2679+
mongoc_client_encryption_get_crypt_shared_version (
2680+
const mongoc_client_encryption_t *enc)
2681+
{
2682+
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
2683+
return _mongoc_crypt_get_crypt_shared_version (enc->crypt);
2684+
#else
2685+
BSON_UNUSED (enc);
2686+
return NULL;
2687+
#endif
2688+
}
2689+
2690+
const char *
2691+
mongoc_client_get_crypt_shared_version (const mongoc_client_t *const client)
2692+
{
2693+
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
2694+
if (!client->topology->crypt) {
2695+
return NULL;
2696+
}
2697+
return _mongoc_crypt_get_crypt_shared_version (client->topology->crypt);
2698+
#else
2699+
BSON_UNUSED (client);
2700+
return NULL;
2701+
#endif
2702+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ mongoc_client_encryption_datakey_opts_set_keymaterial (
274274
const uint8_t *data,
275275
uint32_t len);
276276

277+
MONGOC_EXPORT (const char *)
278+
mongoc_client_encryption_get_crypt_shared_version (
279+
mongoc_client_encryption_t const *enc) BSON_GNUC_WARN_UNUSED_RESULT;
280+
277281
BSON_END_DECLS
278282

279283
#endif /* MONGOC_CLIENT_SIDE_ENCRYPTION_H */

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,10 @@ mongoc_client_enable_auto_encryption (mongoc_client_t *client,
280280
mongoc_auto_encryption_opts_t *opts,
281281
bson_error_t *error);
282282

283+
MONGOC_EXPORT (const char *)
284+
mongoc_client_get_crypt_shared_version (const mongoc_client_t *client)
285+
BSON_GNUC_WARN_UNUSED_RESULT;
286+
283287
MONGOC_EXPORT (bool)
284288
mongoc_client_set_server_api (mongoc_client_t *client,
285289
const mongoc_server_api_t *api,

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,5 +147,8 @@ _mongoc_crypt_rewrap_many_datakey (_mongoc_crypt_t *crypt,
147147
bson_t *doc_out,
148148
bson_error_t *error);
149149

150+
const char *
151+
_mongoc_crypt_get_crypt_shared_version (const _mongoc_crypt_t *crypt);
152+
150153
#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
151154
#endif /* MONGOC_CRYPT_PRIVATE_H */

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,12 @@ _mongoc_crypt_rewrap_many_datakey (_mongoc_crypt_t *crypt,
16511651
return ret;
16521652
}
16531653

1654+
const char *
1655+
_mongoc_crypt_get_crypt_shared_version (const _mongoc_crypt_t *crypt)
1656+
{
1657+
return mongocrypt_crypt_shared_lib_version_string (crypt->handle, NULL);
1658+
}
1659+
16541660
#else
16551661
/* ensure the translation unit is not empty */
16561662
extern int no_mongoc_client_side_encryption;

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

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,9 +2641,10 @@ test_bypass_spawning_via_helper (const char *auto_encryption_opt)
26412641
mongoc_auto_encryption_opts_t *auto_encryption_opts;
26422642
bson_t *kms_providers;
26432643
bson_t *doc_to_insert;
2644-
bson_t *extra;
2644+
bson_t *extra = bson_new ();
26452645
bool ret;
26462646
bson_error_t error;
2647+
bool check_crypt_shared = false;
26472648
mongoc_collection_t *coll;
26482649

26492650
auto_encryption_opts = mongoc_auto_encryption_opts_new ();
@@ -2658,24 +2659,38 @@ test_bypass_spawning_via_helper (const char *auto_encryption_opt)
26582659
} else if (0 == strcmp (auto_encryption_opt, "bypass_query_analysis")) {
26592660
mongoc_auto_encryption_opts_set_bypass_query_analysis (
26602661
auto_encryption_opts, true);
2662+
} else if (0 == strcmp (auto_encryption_opt, "cryptSharedLibRequired")) {
2663+
check_crypt_shared = true;
2664+
char *env_cryptSharedLibPath =
2665+
test_framework_getenv ("MONGOC_TEST_CRYPT_SHARED_LIB_PATH");
2666+
BSON_ASSERT (env_cryptSharedLibPath);
2667+
BSON_APPEND_UTF8 (extra, "cryptSharedLibPath", env_cryptSharedLibPath);
2668+
BSON_APPEND_BOOL (extra, "cryptSharedLibRequired", true);
2669+
bson_free (env_cryptSharedLibPath);
26612670
} else {
26622671
test_error ("Unexpected 'auto_encryption_opt' argument: %s",
26632672
auto_encryption_opt);
26642673
}
26652674

26662675
/* Create a MongoClient with encryption enabled */
26672676
client_encrypted = test_framework_new_default_client ();
2668-
extra = BCON_NEW ("mongocryptdSpawnArgs",
2669-
"[",
2670-
"--pidfilepath=bypass-spawning-mongocryptd.pid",
2671-
"--port=27021",
2672-
"]");
2677+
BCON_APPEND (extra,
2678+
"mongocryptdSpawnArgs",
2679+
"[",
2680+
"--pidfilepath=bypass-spawning-mongocryptd.pid",
2681+
"--port=27021",
2682+
"]");
26732683
mongoc_auto_encryption_opts_set_extra (auto_encryption_opts, extra);
26742684
bson_destroy (extra);
26752685
ret = mongoc_client_enable_auto_encryption (
26762686
client_encrypted, auto_encryption_opts, &error);
26772687
ASSERT_OR_PRINT (ret, error);
26782688

2689+
if (check_crypt_shared) {
2690+
BSON_ASSERT (mongoc_client_get_crypt_shared_version (client_encrypted) !=
2691+
NULL);
2692+
}
2693+
26792694
/* Insert { 'encrypt': 'test' }. Should succeed. */
26802695
coll = mongoc_client_get_collection (client_encrypted, "db", "coll");
26812696
doc_to_insert = BCON_NEW ("unencrypted", "test");
@@ -2710,6 +2725,24 @@ test_bypass_spawning_via_bypassQueryAnalysis (void *unused)
27102725
test_bypass_spawning_via_helper ("bypass_query_analysis");
27112726
}
27122727

2728+
static void
2729+
test_bypass_spawning_via_cryptSharedLibRequired (void *unused)
2730+
{
2731+
BSON_UNUSED (unused);
2732+
test_bypass_spawning_via_helper ("cryptSharedLibRequired");
2733+
}
2734+
2735+
static int
2736+
_skip_if_no_crypt_shared (void)
2737+
{
2738+
char *env = test_framework_getenv ("MONGOC_TEST_CRYPT_SHARED_LIB_PATH");
2739+
if (!env) {
2740+
return 0; // Skip!
2741+
}
2742+
bson_free (env);
2743+
return 1; // Do not skip
2744+
}
2745+
27132746
static mongoc_client_encryption_t *
27142747
_make_kms_certificate_client_encryption (mongoc_client_t *client,
27152748
bson_error_t *error)
@@ -5413,6 +5446,15 @@ test_client_side_encryption_install (TestSuite *suite)
54135446
NULL,
54145447
test_framework_skip_if_no_client_side_encryption,
54155448
test_framework_skip_if_max_wire_version_less_than_8);
5449+
TestSuite_AddFull (suite,
5450+
"/client_side_encryption/bypass_spawning_mongocryptd/"
5451+
"cryptSharedLibRequired",
5452+
test_bypass_spawning_via_cryptSharedLibRequired,
5453+
NULL,
5454+
NULL,
5455+
test_framework_skip_if_no_client_side_encryption,
5456+
test_framework_skip_if_max_wire_version_less_than_8,
5457+
_skip_if_no_crypt_shared);
54165458
TestSuite_AddFull (suite,
54175459
"/client_side_encryption/kms_tls/valid",
54185460
test_kms_tls_cert_valid,

0 commit comments

Comments
 (0)