@@ -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. */
8181static 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 }
0 commit comments