Skip to content

Commit 51939f6

Browse files
authored
MONGOCRYPT-432 Allow keyAltName in encryptedFieldsMap (#1091)
1 parent 823731e commit 51939f6

32 files changed

Lines changed: 1504 additions & 60 deletions

src/mc-efc-private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ typedef enum _supported_query_type_flags {
3737
typedef struct _mc_EncryptedField_t {
3838
supported_query_type_flags supported_queries;
3939
_mongocrypt_buffer_t keyId;
40+
const char *keyAltName;
4041
const char *path;
4142
struct _mc_EncryptedField_t *next;
4243
} mc_EncryptedField_t;

src/mc-efc.c

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,23 +80,48 @@ _parse_supported_query_types(bson_iter_t *iter, supported_query_type_flags *out,
8080
/* _parse_field parses and prepends one field document to efc->fields. */
8181
static bool _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocrypt_status_t *status) {
8282
supported_query_type_flags query_types = SUPPORTS_NO_QUERIES;
83-
bson_iter_t field_iter;
83+
bson_iter_t field_iter, keyid_iter, keyaltname_iter;
8484

8585
BSON_ASSERT_PARAM(efc);
8686
BSON_ASSERT_PARAM(field);
8787

88-
if (!bson_iter_init_find(&field_iter, field, "keyId")) {
89-
CLIENT_ERR("unable to find 'keyId' in 'field' document");
88+
bool has_keyid = false;
89+
bool has_keyaltname = false;
90+
if (bson_iter_init_find(&keyid_iter, field, "keyId")) {
91+
has_keyid = true;
92+
}
93+
if (bson_iter_init_find(&keyaltname_iter, field, "keyAltName")) {
94+
has_keyaltname = true;
95+
}
96+
if (!(has_keyid || has_keyaltname)) {
97+
CLIENT_ERR("unable to find 'keyId' or 'keyAltName' in 'field' document");
9098
return false;
9199
}
92-
if (!BSON_ITER_HOLDS_BINARY(&field_iter)) {
93-
CLIENT_ERR("expected 'fields.keyId' to be type binary, got: %d", (int)bson_iter_type(&field_iter));
100+
if (has_keyid && has_keyaltname) {
101+
CLIENT_ERR("only one of 'keyId' or 'keyAltName may be in 'field' document");
94102
return false;
95103
}
104+
96105
_mongocrypt_buffer_t field_keyid;
97-
if (!_mongocrypt_buffer_from_uuid_iter(&field_keyid, &field_iter)) {
98-
CLIENT_ERR("unable to parse uuid key from 'fields.keyId'");
99-
return false;
106+
if (has_keyid) {
107+
if (!BSON_ITER_HOLDS_BINARY(&keyid_iter)) {
108+
CLIENT_ERR("expected 'fields.keyId' to be type binary, got: %s",
109+
mc_bson_type_to_string(bson_iter_type(&keyid_iter)));
110+
return false;
111+
}
112+
if (!_mongocrypt_buffer_from_uuid_iter(&field_keyid, &keyid_iter)) {
113+
CLIENT_ERR("unable to parse uuid key from 'fields.keyId'");
114+
return false;
115+
}
116+
}
117+
118+
const char *keyAltName = "";
119+
if (has_keyaltname) {
120+
if (!BSON_ITER_HOLDS_UTF8(&keyaltname_iter)) {
121+
CLIENT_ERR("expected 'fields.keyAltName' to be type UTF-8, got: %d", (int)bson_iter_type(&keyaltname_iter));
122+
return false;
123+
}
124+
keyAltName = bson_iter_utf8(&keyaltname_iter, NULL);
100125
}
101126

102127
const char *field_path;
@@ -151,7 +176,12 @@ static bool _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocry
151176

152177
/* Prepend a new mc_EncryptedField_t */
153178
mc_EncryptedField_t *ef = bson_malloc0(sizeof(mc_EncryptedField_t));
154-
_mongocrypt_buffer_copy_to(&field_keyid, &ef->keyId);
179+
if (has_keyid) {
180+
_mongocrypt_buffer_copy_to(&field_keyid, &ef->keyId);
181+
}
182+
if (has_keyaltname) {
183+
ef->keyAltName = bson_strdup(keyAltName);
184+
}
155185
ef->path = bson_strdup(field_path);
156186
ef->next = efc->fields;
157187
ef->supported_queries = query_types;
@@ -194,6 +224,20 @@ bool mc_EncryptedFieldConfig_parse(mc_EncryptedFieldConfig_t *efc,
194224
all_supported_queries |= efc->fields->supported_queries;
195225
}
196226

227+
// Check for duplicate keyAltName values
228+
for (mc_EncryptedField_t *field1 = efc->fields; field1 != NULL; field1 = field1->next) {
229+
if (field1->keyAltName) {
230+
for (mc_EncryptedField_t *field2 = field1->next; field2 != NULL; field2 = field2->next) {
231+
if (field2->keyAltName) {
232+
if (strcmp(field1->keyAltName, field2->keyAltName) == 0) {
233+
CLIENT_ERR("duplicate keyAltName '%s' found in encrypted field config", field1->keyAltName);
234+
return false;
235+
}
236+
}
237+
}
238+
}
239+
}
240+
197241
if (!bson_iter_init_find(&iter, efc_bson, "strEncodeVersion")) {
198242
if (all_supported_queries
199243
& (SUPPORTS_SUBSTRING_PREVIEW_QUERIES | SUPPORTS_SUFFIX_PREVIEW_QUERIES
@@ -229,6 +273,7 @@ void mc_EncryptedFieldConfig_cleanup(mc_EncryptedFieldConfig_t *efc) {
229273
mc_EncryptedField_t *ptr_next = ptr->next;
230274
_mongocrypt_buffer_cleanup(&ptr->keyId);
231275
bson_free((char *)ptr->path);
276+
bson_free((char *)ptr->keyAltName);
232277
bson_free(ptr);
233278
ptr = ptr_next;
234279
}

src/mc-schema-broker-private.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "mc-efc-private.h" // mc_EncryptedFieldConfig_t
2121
#include "mongocrypt-cache-collinfo-private.h"
22+
#include "mongocrypt-key-broker-private.h"
2223
#include "mongocrypt.h"
2324
#include <bson/bson.h>
2425

@@ -102,6 +103,12 @@ bool mc_schema_broker_need_more_schemas(const mc_schema_broker_t *sb);
102103
const mc_EncryptedFieldConfig_t *
103104
mc_schema_broker_get_encryptedFields(const mc_schema_broker_t *sb, const char *coll, mongocrypt_status_t *status);
104105

106+
// mc_schema_broker_maybe_get_encryptedFields returns encryptedFields for a collection if any exists.
107+
//
108+
// Returns NULL if none is found.
109+
const mc_EncryptedFieldConfig_t *
110+
mc_schema_broker_maybe_get_encryptedFields(const mc_schema_broker_t *sb, const char *coll, mongocrypt_status_t *status);
111+
105112
typedef enum {
106113
MC_CMD_SCHEMAS_FOR_CRYPT_SHARED, // target the crypt_shared library.
107114
MC_CMD_SCHEMAS_FOR_MONGOCRYPTD, // target mongocryptd process.
@@ -118,8 +125,23 @@ typedef enum {
118125
// - encryptionInformation: for QE.
119126
//
120127
// Set cmd_target to the intended command destination. This impacts if/how schema information is added.
121-
bool mc_schema_broker_add_schemas_to_cmd(const mc_schema_broker_t *sb,
128+
bool mc_schema_broker_add_schemas_to_cmd(mc_schema_broker_t *sb,
129+
_mongocrypt_key_broker_t *kb,
122130
bson_t *cmd /* in and out */,
123131
mc_cmd_target_t cmd_target,
124132
mongocrypt_status_t *status);
133+
134+
// mc_translate_fields_keyAltName_to_keyId processes a "fields" array from encryptedFields,
135+
// translating keyAltName to keyId for each field document.
136+
//
137+
// @param fields_bson The fields array to process
138+
// @param kb The key broker to use for keyAltName to keyId translation
139+
// @param out The output array to append translated fields to
140+
// @param status Output status
141+
// @return -1 on error, 0 if keyAltName was not found, 1 on success
142+
int mc_translate_fields_keyAltName_to_keyId(const bson_t *fields_bson,
143+
_mongocrypt_key_broker_t *kb,
144+
bson_t *out,
145+
mongocrypt_status_t *status);
146+
125147
#endif // MC_SCHEMA_BROKER_PRIVATE_H

0 commit comments

Comments
 (0)