libmongocrypt-helper 1.20.1.0.1001 → 1.20.3.0.1001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/libmongocrypt/libmongocrypt/CHANGELOG.md +9 -0
- data/ext/libmongocrypt/libmongocrypt/Earthfile +4 -3
- data/ext/libmongocrypt/libmongocrypt/bindings/python/CONTRIBUTING.md +12 -0
- data/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/update-version.sh +1 -1
- data/ext/libmongocrypt/libmongocrypt/doc/releasing.md +10 -0
- data/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json +2 -2
- data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_gcp_request.c +42 -0
- data/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker.c +10 -2
- data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c +25 -4
- data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h +5 -0
- data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c +11 -0
- data/ext/libmongocrypt/libmongocrypt/test/test-gcp-auth.c +51 -0
- data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c +114 -0
- data/lib/libmongocrypt_helper/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b7037c7cdeb5a2f1fe94446f583e7c953539328df98580028a07f46c296689ec
|
|
4
|
+
data.tar.gz: 52a6c553f0e7ee8e0c6aca713184fe9c13f7e5babf97c18e4eff17235b8e7109
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 190dff33114c3f35a8ba07776144bdfde51523e75277176c4c0bf5bdef0be4d500500c3b11eed1520635e43d7b8201faec4faca54da7c99bd119da8d7c3f606e
|
|
7
|
+
data.tar.gz: 20446b82d1838e42ce90980bea22112b4af933cd66daa0984e15b00f1dde2867f408d87f5ed2f86ec146db64b4f0201c0a9be9cdcc30923e48acff5793ab1aa5
|
|
@@ -438,12 +438,12 @@ test-deb-packages-from-ppa:
|
|
|
438
438
|
RUN ./test.out
|
|
439
439
|
|
|
440
440
|
# `sign` uses Garasign to sign a file with the libmongocrypt key.
|
|
441
|
-
# Requires prior authentication with
|
|
441
|
+
# Requires prior authentication with the DevProd Platforms ECR registry (see doc/releasing.md).
|
|
442
442
|
# See: https://docs.devprod.prod.corp.mongodb.com/release-tools-container-images/garasign/garasign_signing/.
|
|
443
443
|
sign:
|
|
444
444
|
ARG --required file_to_sign
|
|
445
445
|
ARG --required output_file
|
|
446
|
-
FROM
|
|
446
|
+
FROM 901841024863.dkr.ecr.us-east-1.amazonaws.com/release-infrastructure/garasign-gpg
|
|
447
447
|
WORKDIR /s
|
|
448
448
|
COPY ${file_to_sign} /s/file
|
|
449
449
|
RUN --secret garasign_username --secret garasign_password \
|
|
@@ -460,8 +460,9 @@ sign:
|
|
|
460
460
|
# An environment with the `silkbomb` command.
|
|
461
461
|
#
|
|
462
462
|
# See https://docs.devprod.prod.corp.mongodb.com/mms/python/src/sbom/silkbomb/ for documentation of silkbomb.
|
|
463
|
+
# Requires prior authentication with the DevProd Platforms ECR registry (see doc/releasing.md).
|
|
463
464
|
silkbomb:
|
|
464
|
-
FROM
|
|
465
|
+
FROM 901841024863.dkr.ecr.us-east-1.amazonaws.com/release-infrastructure/silkbomb:2.0
|
|
465
466
|
# Alias the silkbomb executable to a simpler name:
|
|
466
467
|
RUN ln -s /python/src/sbom/silkbomb/bin /usr/local/bin/silkbomb
|
|
467
468
|
|
|
@@ -28,6 +28,18 @@ bash scripts/update-version.sh <new-version>
|
|
|
28
28
|
This will set the version in `scripts/libmongocrypt-version.sh` and update `sbom.json` to reflect
|
|
29
29
|
the new vendored version of `libmongocrypt`.
|
|
30
30
|
|
|
31
|
+
This pulls the `silkbomb` image from the DevProd Platforms ECR registry. Authenticate to the ECR
|
|
32
|
+
registry with the container launcher (`docker` or `podman`) before running the script:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
aws sso login --profile ECRScopedAccess-901841024863
|
|
36
|
+
|
|
37
|
+
# Authenticate "podman" or "docker"
|
|
38
|
+
CONTAINER_LAUNCHER="podman"
|
|
39
|
+
|
|
40
|
+
aws ecr get-login-password --region us-east-1 --profile ECRScopedAccess-901841024863 | $CONTAINER_LAUNCHER login --username AWS --password-stdin 901841024863.dkr.ecr.us-east-1.amazonaws.com
|
|
41
|
+
```
|
|
42
|
+
|
|
31
43
|
## Building wheels
|
|
32
44
|
|
|
33
45
|
To build wheels, run `scripts/release.sh`. It will build the appropriate wheel for the current system
|
|
@@ -21,7 +21,7 @@ else
|
|
|
21
21
|
fi
|
|
22
22
|
|
|
23
23
|
echo "pkg:github/mongodb/libmongocrypt@$LIBMONGOCRYPT_VERSION" > purls.txt
|
|
24
|
-
$DOCKER run --platform="linux/amd64" -it --rm -v $(pwd):$(pwd)
|
|
24
|
+
$DOCKER run --platform="linux/amd64" -it --rm -v $(pwd):$(pwd) 901841024863.dkr.ecr.us-east-1.amazonaws.com/release-infrastructure/silkbomb:2.0 update --purls=$(pwd)/purls.txt -o $(pwd)/sbom.json
|
|
25
25
|
rm purls.txt
|
|
26
26
|
|
|
27
27
|
popd
|
|
@@ -93,6 +93,15 @@ Do the following when releasing:
|
|
|
93
93
|
```bash
|
|
94
94
|
./.evergreen/earthly.sh +sbom-generate-new-serial-number
|
|
95
95
|
```
|
|
96
|
+
This pulls the `silkbomb` image from the DevProd Platforms ECR registry. Authenticate to the ECR registry with the container launcher (`docker` or `podman`):
|
|
97
|
+
```bash
|
|
98
|
+
aws sso login --profile ECRScopedAccess-901841024863
|
|
99
|
+
|
|
100
|
+
# Authenticate "podman" or "docker"
|
|
101
|
+
CONTAINER_LAUNCHER="podman"
|
|
102
|
+
|
|
103
|
+
aws ecr get-login-password --region us-east-1 --profile ECRScopedAccess-901841024863 | $CONTAINER_LAUNCHER login --username AWS --password-stdin 901841024863.dkr.ecr.us-east-1.amazonaws.com
|
|
104
|
+
```
|
|
96
105
|
Commit resulting `etc/cyclonedx.sbom.json` and push to `rx.y`.
|
|
97
106
|
- Remove yourself from the [releases team](https://github.com/orgs/mongodb/teams/dbx-c-cxx-releases) on GitHub via [MANA](https://mana.corp.mongodb.com/resources/68029673d39aa9f7de6399f9).
|
|
98
107
|
- If this is a new non-patch release (e.g. `x.y.0`):
|
|
@@ -130,6 +139,7 @@ Do the following when releasing:
|
|
|
130
139
|
```bash
|
|
131
140
|
./.evergreen/earthly.sh +sbom-generate-new-serial-number
|
|
132
141
|
```
|
|
142
|
+
Requires AWS SSO access to the `ECRScopedAccess-901841024863` profile (see note above).
|
|
133
143
|
Commit resulting `etc/cyclonedx.sbom.json`.
|
|
134
144
|
- Update the release on the [Jira releases page](https://jira.mongodb.org/projects/MONGOCRYPT/versions).
|
|
135
145
|
- Record the release on [C/C++ Release Info](https://docs.google.com/spreadsheets/d/1yHfGmDnbA5-Qt8FX4tKWC5xk9AhzYZx1SKF4AD36ecY/edit?usp=sharing). This is done to leave commentary about the process.
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
}
|
|
58
58
|
],
|
|
59
59
|
"metadata": {
|
|
60
|
-
"timestamp": "2026-
|
|
60
|
+
"timestamp": "2026-08-07T17:48:10.053548+00:00",
|
|
61
61
|
"tools": [
|
|
62
62
|
{
|
|
63
63
|
"externalReferences": [
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
}
|
|
101
101
|
]
|
|
102
102
|
},
|
|
103
|
-
"serialNumber": "urn:uuid:
|
|
103
|
+
"serialNumber": "urn:uuid:464d2591-6478-4559-a1c4-9a726248fc1e",
|
|
104
104
|
"version": 1,
|
|
105
105
|
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
|
106
106
|
"bomFormat": "CycloneDX",
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
#include "kms_message_private.h"
|
|
21
21
|
#include "kms_request_opt_private.h"
|
|
22
22
|
|
|
23
|
+
#include <ctype.h>
|
|
24
|
+
|
|
23
25
|
/* Set a default expiration of 5 minutes for JSON Web Tokens (GCP allows up to
|
|
24
26
|
* one hour) */
|
|
25
27
|
#define JWT_EXPIRATION_SECS 5 * 60
|
|
@@ -145,6 +147,38 @@ done:
|
|
|
145
147
|
return req;
|
|
146
148
|
}
|
|
147
149
|
|
|
150
|
+
/* _check_key_identifier returns true if `value` is safe to use as a URL path segment.
|
|
151
|
+
*
|
|
152
|
+
* Key identifiers may originate from key vault documents or caller-supplied options. They are
|
|
153
|
+
* formatted into the request path, so an unescaped '/', '?', '#', space, or CR/LF would rewrite
|
|
154
|
+
* the request target or inject header lines into the request.
|
|
155
|
+
*
|
|
156
|
+
* Only the RFC 3986 unreserved characters are permitted. This is a superset of what GCP itself
|
|
157
|
+
* accepts, so it does not reject any identifier that would otherwise work:
|
|
158
|
+
* - keyRing and keyName must match `[a-zA-Z0-9_-]{1,63}`. See
|
|
159
|
+
* https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings/create and
|
|
160
|
+
* https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys/create
|
|
161
|
+
* - projectId is 6-30 characters of lowercase letters, numbers, and hyphens. See
|
|
162
|
+
* https://cloud.google.com/resource-manager/docs/creating-managing-projects
|
|
163
|
+
* - location is a Cloud location name (e.g. "global", "us-east1").
|
|
164
|
+
* - keyVersion is a positive integer.
|
|
165
|
+
*
|
|
166
|
+
* `value` is not included in the error message: it is untrusted, and the error may be logged. */
|
|
167
|
+
static bool
|
|
168
|
+
_check_key_identifier (kms_request_t *req, const char *name, const char *value)
|
|
169
|
+
{
|
|
170
|
+
const char *c;
|
|
171
|
+
|
|
172
|
+
for (c = value; *c != '\0'; c++) {
|
|
173
|
+
if (!isalnum ((unsigned char) *c) && *c != '-' && *c != '.' && *c != '_' &&
|
|
174
|
+
*c != '~') {
|
|
175
|
+
KMS_ERROR (req, "Invalid character in GCP KMS key identifier: %s", name);
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
|
|
148
182
|
static kms_request_t *
|
|
149
183
|
_encrypt_decrypt_common (const char *encrypt_decrypt,
|
|
150
184
|
const char *host,
|
|
@@ -192,6 +226,14 @@ _encrypt_decrypt_common (const char *encrypt_decrypt,
|
|
|
192
226
|
goto done;
|
|
193
227
|
}
|
|
194
228
|
|
|
229
|
+
if (!_check_key_identifier (req, "projectId", project_id) ||
|
|
230
|
+
!_check_key_identifier (req, "location", location) ||
|
|
231
|
+
!_check_key_identifier (req, "keyRing", key_ring_name) ||
|
|
232
|
+
!_check_key_identifier (req, "keyName", key_name) ||
|
|
233
|
+
(key_version && !_check_key_identifier (req, "keyVersion", key_version))) {
|
|
234
|
+
goto done;
|
|
235
|
+
}
|
|
236
|
+
|
|
195
237
|
value_base64 = kms_message_raw_to_b64 (value, value_len);
|
|
196
238
|
if (!value_base64) {
|
|
197
239
|
KMS_ERROR (req, "Could not bases64-encode plaintext");
|
|
@@ -323,7 +323,11 @@ bool mc_schema_broker_satisfy_from_collinfo(mc_schema_broker_t *sb,
|
|
|
323
323
|
CLIENT_ERR("failed to find 'name' in collinfo in database: %s", sb->db);
|
|
324
324
|
return false;
|
|
325
325
|
}
|
|
326
|
-
|
|
326
|
+
uint32_t coll_len;
|
|
327
|
+
coll = bson_iter_utf8(&name_iter, &coll_len);
|
|
328
|
+
if (!_mongocrypt_check_no_embedded_nul(coll, coll_len, "collection name in collinfo", status)) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
327
331
|
}
|
|
328
332
|
|
|
329
333
|
// Cache the received collinfo.
|
|
@@ -508,7 +512,11 @@ bool mc_schema_broker_satisfy_from_create_or_collMod(mc_schema_broker_t *sb,
|
|
|
508
512
|
CLIENT_ERR("Failed to get collection name from command");
|
|
509
513
|
return false;
|
|
510
514
|
}
|
|
511
|
-
|
|
515
|
+
uint32_t coll_len;
|
|
516
|
+
const char *coll = bson_iter_utf8(&iter, &coll_len);
|
|
517
|
+
if (!_mongocrypt_check_no_embedded_nul(coll, coll_len, "collection name", status)) {
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
512
520
|
|
|
513
521
|
// Check if schema was requested.
|
|
514
522
|
mc_schema_entry_t *found = NULL;
|
|
@@ -2303,7 +2303,11 @@ static bool _check_cmd_for_auto_encrypt_bulkWrite(mongocrypt_binary_t *cmd,
|
|
|
2303
2303
|
return false;
|
|
2304
2304
|
}
|
|
2305
2305
|
|
|
2306
|
-
|
|
2306
|
+
uint32_t target_ns_len;
|
|
2307
|
+
const char *target_ns = bson_iter_utf8(&ns_iter, &target_ns_len);
|
|
2308
|
+
if (!_mongocrypt_check_no_embedded_nul(target_ns, target_ns_len, "namespace in `bulkWrite` command", status)) {
|
|
2309
|
+
return false;
|
|
2310
|
+
}
|
|
2307
2311
|
// Parse `target_ns` into "<db>.<coll>"
|
|
2308
2312
|
const char *dot = strstr(target_ns, ".");
|
|
2309
2313
|
if (!dot) {
|
|
@@ -2375,7 +2379,12 @@ _check_cmd_for_auto_encrypt(mongocrypt_binary_t *cmd, bool *bypass, char **targe
|
|
|
2375
2379
|
}
|
|
2376
2380
|
|
|
2377
2381
|
if (BSON_ITER_HOLDS_UTF8(&target_coll_iter)) {
|
|
2378
|
-
|
|
2382
|
+
uint32_t target_coll_len;
|
|
2383
|
+
const char *target_coll_str = bson_iter_utf8(&target_coll_iter, &target_coll_len);
|
|
2384
|
+
if (!_mongocrypt_check_no_embedded_nul(target_coll_str, target_coll_len, "collection name", status)) {
|
|
2385
|
+
return false;
|
|
2386
|
+
}
|
|
2387
|
+
*target_coll = bson_strdup(target_coll_str);
|
|
2379
2388
|
} else {
|
|
2380
2389
|
*target_coll = NULL;
|
|
2381
2390
|
}
|
|
@@ -2572,7 +2581,11 @@ static bool find_collections_in_pipeline(mc_schema_broker_t *sb,
|
|
|
2572
2581
|
stage_key);
|
|
2573
2582
|
return false;
|
|
2574
2583
|
}
|
|
2575
|
-
|
|
2584
|
+
uint32_t from_len;
|
|
2585
|
+
const char *from = bson_iter_utf8(&lookup_iter, &from_len);
|
|
2586
|
+
if (!_mongocrypt_check_no_embedded_nul(from, from_len, "'from' collection name", status)) {
|
|
2587
|
+
return false;
|
|
2588
|
+
}
|
|
2576
2589
|
if (!mc_schema_broker_request(sb, db, from, status)) {
|
|
2577
2590
|
return false;
|
|
2578
2591
|
}
|
|
@@ -2631,7 +2644,11 @@ static bool find_collections_in_pipeline(mc_schema_broker_t *sb,
|
|
|
2631
2644
|
stage_key);
|
|
2632
2645
|
return false;
|
|
2633
2646
|
}
|
|
2634
|
-
|
|
2647
|
+
uint32_t coll_len;
|
|
2648
|
+
const char *coll = bson_iter_utf8(&unionWith_iter, &coll_len);
|
|
2649
|
+
if (!_mongocrypt_check_no_embedded_nul(coll, coll_len, "'coll' collection name", status)) {
|
|
2650
|
+
return false;
|
|
2651
|
+
}
|
|
2635
2652
|
if (!mc_schema_broker_request(sb, db, coll, status)) {
|
|
2636
2653
|
return false;
|
|
2637
2654
|
}
|
|
@@ -2722,6 +2739,10 @@ bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t
|
|
|
2722
2739
|
return _mongocrypt_ctx_fail_w_msg(ctx, "invalid db");
|
|
2723
2740
|
}
|
|
2724
2741
|
|
|
2742
|
+
if (strchr(ectx->cmd_db, '.')) {
|
|
2743
|
+
return _mongocrypt_ctx_fail_w_msg(ctx, "invalid db: must not contain a dot");
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2725
2746
|
if (0 == strcmp(ectx->cmd_name, "bulkWrite")) {
|
|
2726
2747
|
// Handle `bulkWrite` as a special case.
|
|
2727
2748
|
// `bulkWrite` includes the target namespaces in an `nsInfo` field.
|
|
@@ -161,6 +161,11 @@ typedef enum {
|
|
|
161
161
|
|
|
162
162
|
bool _mongocrypt_validate_and_copy_string(const char *in, int32_t in_len, char **out) MONGOCRYPT_WARN_UNUSED_RESULT;
|
|
163
163
|
|
|
164
|
+
/* _mongocrypt_check_no_embedded_nul returns false and sets @status if @str contains an embedded null byte. See
|
|
165
|
+
* MONGOCRYPT-977. */
|
|
166
|
+
bool _mongocrypt_check_no_embedded_nul(const char *str, uint32_t len, const char *what, mongocrypt_status_t *status)
|
|
167
|
+
MONGOCRYPT_WARN_UNUSED_RESULT;
|
|
168
|
+
|
|
164
169
|
char *_mongocrypt_new_string_from_bytes(const void *in, int len);
|
|
165
170
|
|
|
166
171
|
/* _mongocrypt_needs_credentials returns true if @crypt was configured to
|
|
@@ -913,6 +913,17 @@ uint64_t mongocrypt_crypt_shared_lib_version(const mongocrypt_t *crypt) {
|
|
|
913
913
|
return crypt->csfle.get_version();
|
|
914
914
|
}
|
|
915
915
|
|
|
916
|
+
bool _mongocrypt_check_no_embedded_nul(const char *str, uint32_t len, const char *what, mongocrypt_status_t *status) {
|
|
917
|
+
BSON_ASSERT_PARAM(str);
|
|
918
|
+
BSON_ASSERT_PARAM(what);
|
|
919
|
+
|
|
920
|
+
if (strlen(str) != (size_t)len) {
|
|
921
|
+
CLIENT_ERR("%s must not contain an embedded null byte", what);
|
|
922
|
+
return false;
|
|
923
|
+
}
|
|
924
|
+
return true;
|
|
925
|
+
}
|
|
926
|
+
|
|
916
927
|
bool _mongocrypt_validate_and_copy_string(const char *in, int32_t in_len, char **out) {
|
|
917
928
|
BSON_ASSERT_PARAM(out);
|
|
918
929
|
|
|
@@ -242,7 +242,58 @@ static void _test_encrypt_with_accesstoken(_mongocrypt_tester_t *tester) {
|
|
|
242
242
|
mongocrypt_destroy(crypt);
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
// Test a CRLF in a key vault document's keyName. Regression test for MONGOCRYPT-960.
|
|
246
|
+
static void _test_crlf_in_gcp_masterkey(_mongocrypt_tester_t *tester) {
|
|
247
|
+
mongocrypt_t *crypt;
|
|
248
|
+
mongocrypt_ctx_t *ctx;
|
|
249
|
+
mongocrypt_binary_t *uuid;
|
|
250
|
+
const char *uuid_data = "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61";
|
|
251
|
+
|
|
252
|
+
// A key vault document whose masterKey.keyName contains a CRLF.
|
|
253
|
+
// clang-format off
|
|
254
|
+
const char *key_doc = BSON_STR({
|
|
255
|
+
"status" : 1,
|
|
256
|
+
"_id" : {"$binary" : {"base64" : "YWFhYWFhYWFhYWFhYWFhYQ==", "subType" : "04"}},
|
|
257
|
+
"masterKey" : {
|
|
258
|
+
"provider" : "gcp",
|
|
259
|
+
"projectId" : "test",
|
|
260
|
+
"location" : "global",
|
|
261
|
+
"keyRing" : "test",
|
|
262
|
+
"keyName" : "test\r\nFOOBAR: injected"
|
|
263
|
+
},
|
|
264
|
+
"updateDate" : {"$date" : {"$numberLong" : "1557827033449"}},
|
|
265
|
+
"creationDate" : {"$date" : {"$numberLong" : "1557827033449"}},
|
|
266
|
+
"keyMaterial" : {
|
|
267
|
+
"$binary" : {
|
|
268
|
+
"base64" : "PwwOESbKs57YTJtGSCsuAJbv9VWRHjLdPdziUVxH0K9woZUka4SghSwJlw9n6TU/dYHFODvSa4p7bfKzS6U8kGFvOnd7LcPU63IkTek4qZEbGpTRwI5lMT4FFWdpYpUf",
|
|
269
|
+
"subType" : "00"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
// clang-format on
|
|
274
|
+
|
|
275
|
+
crypt = mongocrypt_new();
|
|
276
|
+
ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, TEST_BSON("{'gcp': {'accessToken': 'foobar'}}")), crypt);
|
|
277
|
+
ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
|
|
278
|
+
ctx = mongocrypt_ctx_new(crypt);
|
|
279
|
+
uuid = mongocrypt_binary_new_from_data((uint8_t *)uuid_data, UUID_LEN);
|
|
280
|
+
ASSERT_OK(mongocrypt_ctx_setopt_key_id(ctx, uuid), ctx);
|
|
281
|
+
ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
|
|
282
|
+
ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON("{'v': 1}")), ctx);
|
|
283
|
+
|
|
284
|
+
ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
|
|
285
|
+
/* Constructing the KMS request fails. No request is sent. */
|
|
286
|
+
ASSERT_FAILS(mongocrypt_ctx_mongo_feed(ctx, TEST_BSON_STR(key_doc)),
|
|
287
|
+
ctx,
|
|
288
|
+
"Invalid character in GCP KMS key identifier: keyName");
|
|
289
|
+
|
|
290
|
+
mongocrypt_binary_destroy(uuid);
|
|
291
|
+
mongocrypt_ctx_destroy(ctx);
|
|
292
|
+
mongocrypt_destroy(crypt);
|
|
293
|
+
}
|
|
294
|
+
|
|
245
295
|
void _mongocrypt_tester_install_gcp_auth(_mongocrypt_tester_t *tester) {
|
|
296
|
+
INSTALL_TEST(_test_crlf_in_gcp_masterkey);
|
|
246
297
|
INSTALL_TEST(_test_createdatakey_with_credentials);
|
|
247
298
|
INSTALL_TEST(_test_encrypt_with_credentials);
|
|
248
299
|
INSTALL_TEST(_test_createdatakey_with_accesstoken);
|
|
@@ -362,6 +362,119 @@ static void _test_encrypt_init(_mongocrypt_tester_t *tester) {
|
|
|
362
362
|
mongocrypt_destroy(crypt);
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
+
/* Test that a db name containing a dot or an embedded NUL is rejected.
|
|
366
|
+
* A db name like "a.b" would otherwise produce the namespace "a.b.coll",
|
|
367
|
+
* retargeting the operation at database "a" and collection "b.coll".
|
|
368
|
+
* Regression test for MONGOCRYPT-977. */
|
|
369
|
+
static void _test_encrypt_init_invalid_db_collection(_mongocrypt_tester_t *tester) {
|
|
370
|
+
mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT);
|
|
371
|
+
|
|
372
|
+
{
|
|
373
|
+
/* Dot in db name. */
|
|
374
|
+
mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
|
|
375
|
+
ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "a.b", -1, TEST_FILE("./test/example/cmd.json")),
|
|
376
|
+
ctx,
|
|
377
|
+
"invalid db");
|
|
378
|
+
mongocrypt_ctx_destroy(ctx);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
{
|
|
382
|
+
/* Embedded NUL in db name. */
|
|
383
|
+
const char db[] = "a\0b";
|
|
384
|
+
mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
|
|
385
|
+
ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, db, 3, TEST_FILE("./test/example/cmd.json")), ctx, "invalid db");
|
|
386
|
+
mongocrypt_ctx_destroy(ctx);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
{
|
|
390
|
+
/* A dot in a collection name is legal, and must keep working. */
|
|
391
|
+
mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
|
|
392
|
+
ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_BSON("{'find': 'a.b'}")), ctx);
|
|
393
|
+
mongocrypt_ctx_destroy(ctx);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
{
|
|
397
|
+
/* Embedded NUL in the collection name of the command. */
|
|
398
|
+
bson_t *cmd = bson_new();
|
|
399
|
+
BSON_ASSERT(bson_append_utf8(cmd, "find", -1, "a\0b", 3));
|
|
400
|
+
mongocrypt_binary_t *bin = mongocrypt_binary_new_from_data((uint8_t *)bson_get_data(cmd), cmd->len);
|
|
401
|
+
mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
|
|
402
|
+
ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "test", -1, bin),
|
|
403
|
+
ctx,
|
|
404
|
+
"collection name must not contain an embedded null byte");
|
|
405
|
+
mongocrypt_ctx_destroy(ctx);
|
|
406
|
+
mongocrypt_binary_destroy(bin);
|
|
407
|
+
bson_destroy(cmd);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
{
|
|
411
|
+
/* Embedded NUL in the `bulkWrite` nsInfo namespace. */
|
|
412
|
+
bson_t *cmd = bson_new();
|
|
413
|
+
bson_array_builder_t *nsInfo;
|
|
414
|
+
bson_t ns0;
|
|
415
|
+
BSON_ASSERT(BSON_APPEND_INT32(cmd, "bulkWrite", 1));
|
|
416
|
+
BSON_ASSERT(BSON_APPEND_ARRAY_BUILDER_BEGIN(cmd, "nsInfo", &nsInfo));
|
|
417
|
+
BSON_ASSERT(bson_array_builder_append_document_begin(nsInfo, &ns0));
|
|
418
|
+
BSON_ASSERT(bson_append_utf8(&ns0, "ns", -1, "db.coll\0evil", 12));
|
|
419
|
+
BSON_ASSERT(bson_array_builder_append_document_end(nsInfo, &ns0));
|
|
420
|
+
BSON_ASSERT(bson_append_array_builder_end(cmd, nsInfo));
|
|
421
|
+
mongocrypt_binary_t *bin = mongocrypt_binary_new_from_data((uint8_t *)bson_get_data(cmd), cmd->len);
|
|
422
|
+
mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
|
|
423
|
+
ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "test", -1, bin), ctx, "must not contain an embedded null byte");
|
|
424
|
+
mongocrypt_ctx_destroy(ctx);
|
|
425
|
+
mongocrypt_binary_destroy(bin);
|
|
426
|
+
bson_destroy(cmd);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
{
|
|
430
|
+
/* Embedded NUL in a $lookup 'from' collection name. */
|
|
431
|
+
bson_t *cmd = bson_new();
|
|
432
|
+
bson_array_builder_t *pipeline;
|
|
433
|
+
bson_t stage, lookup;
|
|
434
|
+
BSON_ASSERT(BSON_APPEND_UTF8(cmd, "aggregate", "coll"));
|
|
435
|
+
BSON_ASSERT(BSON_APPEND_ARRAY_BUILDER_BEGIN(cmd, "pipeline", &pipeline));
|
|
436
|
+
BSON_ASSERT(bson_array_builder_append_document_begin(pipeline, &stage));
|
|
437
|
+
BSON_ASSERT(BSON_APPEND_DOCUMENT_BEGIN(&stage, "$lookup", &lookup));
|
|
438
|
+
BSON_ASSERT(bson_append_utf8(&lookup, "from", -1, "a\0b", 3));
|
|
439
|
+
BSON_ASSERT(bson_append_document_end(&stage, &lookup));
|
|
440
|
+
BSON_ASSERT(bson_array_builder_append_document_end(pipeline, &stage));
|
|
441
|
+
BSON_ASSERT(bson_append_array_builder_end(cmd, pipeline));
|
|
442
|
+
mongocrypt_binary_t *bin = mongocrypt_binary_new_from_data((uint8_t *)bson_get_data(cmd), cmd->len);
|
|
443
|
+
mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
|
|
444
|
+
ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "test", -1, bin),
|
|
445
|
+
ctx,
|
|
446
|
+
"'from' collection name must not contain an embedded null byte");
|
|
447
|
+
mongocrypt_ctx_destroy(ctx);
|
|
448
|
+
mongocrypt_binary_destroy(bin);
|
|
449
|
+
bson_destroy(cmd);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
{
|
|
453
|
+
/* Embedded NUL in a $unionWith 'coll' collection name. */
|
|
454
|
+
bson_t *cmd = bson_new();
|
|
455
|
+
bson_array_builder_t *pipeline;
|
|
456
|
+
bson_t stage, unionWith;
|
|
457
|
+
BSON_ASSERT(BSON_APPEND_UTF8(cmd, "aggregate", "coll"));
|
|
458
|
+
BSON_ASSERT(BSON_APPEND_ARRAY_BUILDER_BEGIN(cmd, "pipeline", &pipeline));
|
|
459
|
+
BSON_ASSERT(bson_array_builder_append_document_begin(pipeline, &stage));
|
|
460
|
+
BSON_ASSERT(BSON_APPEND_DOCUMENT_BEGIN(&stage, "$unionWith", &unionWith));
|
|
461
|
+
BSON_ASSERT(bson_append_utf8(&unionWith, "coll", -1, "a\0b", 3));
|
|
462
|
+
BSON_ASSERT(bson_append_document_end(&stage, &unionWith));
|
|
463
|
+
BSON_ASSERT(bson_array_builder_append_document_end(pipeline, &stage));
|
|
464
|
+
BSON_ASSERT(bson_append_array_builder_end(cmd, pipeline));
|
|
465
|
+
mongocrypt_binary_t *bin = mongocrypt_binary_new_from_data((uint8_t *)bson_get_data(cmd), cmd->len);
|
|
466
|
+
mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
|
|
467
|
+
ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "test", -1, bin),
|
|
468
|
+
ctx,
|
|
469
|
+
"'coll' collection name must not contain an embedded null byte");
|
|
470
|
+
mongocrypt_ctx_destroy(ctx);
|
|
471
|
+
mongocrypt_binary_destroy(bin);
|
|
472
|
+
bson_destroy(cmd);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
mongocrypt_destroy(crypt);
|
|
476
|
+
}
|
|
477
|
+
|
|
365
478
|
static void _test_encrypt_need_collinfo(_mongocrypt_tester_t *tester) {
|
|
366
479
|
mongocrypt_t *crypt;
|
|
367
480
|
mongocrypt_ctx_t *ctx;
|
|
@@ -6830,6 +6943,7 @@ static void _test_qe_keyAltName_kms(_mongocrypt_tester_t *tester) {
|
|
|
6830
6943
|
void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) {
|
|
6831
6944
|
INSTALL_TEST(_test_explicit_encrypt_init);
|
|
6832
6945
|
INSTALL_TEST(_test_encrypt_init);
|
|
6946
|
+
INSTALL_TEST(_test_encrypt_init_invalid_db_collection);
|
|
6833
6947
|
INSTALL_TEST(_test_encrypt_need_collinfo);
|
|
6834
6948
|
INSTALL_TEST(_test_encrypt_need_markings);
|
|
6835
6949
|
INSTALL_TEST(_test_encrypt_csfle_no_needs_markings);
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: libmongocrypt-helper
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.20.
|
|
4
|
+
version: 1.20.3.0.1001
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- The MongoDB Ruby Team
|
|
@@ -1250,7 +1250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
1250
1250
|
- !ruby/object:Gem::Version
|
|
1251
1251
|
version: '0'
|
|
1252
1252
|
requirements: []
|
|
1253
|
-
rubygems_version: 4.0.
|
|
1253
|
+
rubygems_version: 4.0.19
|
|
1254
1254
|
specification_version: 4
|
|
1255
1255
|
summary: libmongocrypt convenience package
|
|
1256
1256
|
test_files: []
|