Skip to content

Commit a8560d7

Browse files
[CDRIVER-4540] Define a success test for CreateEncryptedCollection (#1176)
Define a success test for CreateEncryptedCollection Creates an encrypted collection using the CEC API, then uses the generated key to encrypt a value, and then inserts that value into the new encrypted collection. Expects success.
1 parent ad85279 commit a8560d7

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

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

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6417,6 +6417,122 @@ test_create_encrypted_collection_bad_keyId (void *unused)
64176417
mongoc_client_destroy (client);
64186418
}
64196419

6420+
// Implements Prose Test 21. Case: 4.
6421+
static void
6422+
test_create_encrypted_collection_insert (void *unused)
6423+
{
6424+
BSON_UNUSED (unused);
6425+
bson_error_t error = {0};
6426+
mongoc_client_t *const client = test_framework_new_default_client ();
6427+
bson_t *const kmsProviders = _make_kms_providers (false, true);
6428+
6429+
const char *const dbName = "cec-test-db";
6430+
6431+
// Drop prior data
6432+
{
6433+
mongoc_collection_t *const coll =
6434+
mongoc_client_get_collection (client, "keyvault", "datakeys");
6435+
if (coll) {
6436+
mongoc_collection_drop (coll, &error);
6437+
bool okay =
6438+
error.code == 0 || strstr (error.message, "ns not found") != NULL;
6439+
ASSERT_OR_PRINT (okay, error);
6440+
}
6441+
mongoc_collection_destroy (coll);
6442+
6443+
mongoc_database_t *const db = mongoc_client_get_database (client, dbName);
6444+
ASSERT_OR_PRINT (mongoc_database_drop (db, &error), error);
6445+
mongoc_database_destroy (db);
6446+
}
6447+
6448+
// Create a CE
6449+
mongoc_client_encryption_opts_t *const ceOpts =
6450+
mongoc_client_encryption_opts_new ();
6451+
mongoc_client_encryption_opts_set_kms_providers (ceOpts, kmsProviders);
6452+
mongoc_client_encryption_opts_set_keyvault_namespace (
6453+
ceOpts, "keyvault", "datakeys");
6454+
mongoc_client_encryption_opts_set_keyvault_client (ceOpts, client);
6455+
mongoc_client_encryption_t *const ce =
6456+
mongoc_client_encryption_new (ceOpts, &error);
6457+
mongoc_client_encryption_opts_destroy (ceOpts);
6458+
ASSERT_OR_PRINT (ce, error);
6459+
6460+
// Create the encrypted collection
6461+
bsonBuildDecl (ccOpts,
6462+
kv ("encryptedFields",
6463+
doc (kv ("fields",
6464+
array (doc (kv ("path", cstr ("ssn")),
6465+
kv ("bsonType", cstr ("string")),
6466+
kv ("keyId", null)))))));
6467+
mongoc_database_t *const db = mongoc_client_get_database (client, dbName);
6468+
mongoc_client_encryption_datakey_opts_t *const dkOpts =
6469+
mongoc_client_encryption_datakey_opts_new ();
6470+
bson_t new_opts;
6471+
mongoc_collection_t *const coll =
6472+
mongoc_client_encryption_create_encrypted_collection (
6473+
ce, db, "testing1", &ccOpts, &new_opts, "local", dkOpts, &error);
6474+
ASSERT_OR_PRINT (coll, error);
6475+
bson_destroy (&ccOpts);
6476+
6477+
// Extract the encryption key ID that was generated by
6478+
// CreateEncryptedCollection:
6479+
bson_value_t new_keyid;
6480+
bsonParse (
6481+
new_opts,
6482+
require (
6483+
keyWithType ("encryptedFields", doc),
6484+
parse (require (
6485+
keyWithType ("fields", array),
6486+
visitEach (require (type (doc)),
6487+
parse (require (key ("keyId"),
6488+
require (type (binary)),
6489+
do({
6490+
bson_value_copy (
6491+
bson_iter_value (
6492+
(bson_iter_t *) &bsonVisitIter),
6493+
&new_keyid);
6494+
}),
6495+
halt)))))));
6496+
ASSERT_CMPSTR (bsonParseError, NULL);
6497+
6498+
// Generate some plaintext:
6499+
bson_value_t plain;
6500+
plain.value_type = BSON_TYPE_UTF8;
6501+
plain.value.v_utf8.str = "123-45-6789";
6502+
plain.value.v_utf8.len = (uint32_t) strlen (plain.value.v_utf8.str);
6503+
6504+
// Encrypt the value using the new encryption key:
6505+
mongoc_client_encryption_encrypt_opts_t *eo =
6506+
mongoc_client_encryption_encrypt_opts_new ();
6507+
mongoc_client_encryption_encrypt_opts_set_keyid (eo, &new_keyid);
6508+
mongoc_client_encryption_encrypt_opts_set_algorithm (
6509+
eo, MONGOC_ENCRYPT_ALGORITHM_UNINDEXED);
6510+
bson_value_t ciphertext;
6511+
bool okay =
6512+
mongoc_client_encryption_encrypt (ce, &plain, eo, &ciphertext, &error);
6513+
ASSERT_OR_PRINT (okay, error);
6514+
mongoc_client_encryption_encrypt_opts_destroy (eo);
6515+
bson_value_destroy (&new_keyid);
6516+
6517+
// Insert the ciphertext:
6518+
bsonBuildDecl (doc, kv ("ssn", value (ciphertext)));
6519+
okay = mongoc_collection_insert_one (coll, &doc, NULL, NULL, &error);
6520+
ASSERT_OR_PRINT (okay, error);
6521+
// Success!
6522+
6523+
bson_destroy (&doc);
6524+
bson_value_destroy (&ciphertext);
6525+
bson_destroy (kmsProviders);
6526+
mongoc_client_encryption_datakey_opts_destroy (dkOpts);
6527+
mongoc_collection_destroy (coll);
6528+
mongoc_database_drop (db, &error);
6529+
mongoc_database_destroy (db);
6530+
mongoc_client_encryption_destroy (ce);
6531+
mongoc_client_destroy (client);
6532+
bson_destroy (&new_opts);
6533+
}
6534+
6535+
64206536
typedef struct listen_socket {
64216537
mongoc_socket_t *socket;
64226538
mongoc_cond_t cond;
@@ -6890,6 +7006,15 @@ test_client_side_encryption_install (TestSuite *suite)
68907006
test_framework_skip_if_no_client_side_encryption,
68917007
test_framework_skip_if_max_wire_version_less_than_17,
68927008
test_framework_skip_if_single);
7009+
TestSuite_AddFull (
7010+
suite,
7011+
"/client_side_encryption/createEncryptedCollection/insert",
7012+
test_create_encrypted_collection_insert,
7013+
NULL,
7014+
NULL,
7015+
test_framework_skip_if_no_client_side_encryption,
7016+
test_framework_skip_if_max_wire_version_less_than_17,
7017+
test_framework_skip_if_single);
68937018
TestSuite_AddFull (
68947019
suite,
68957020
"/client_side_encryption/bypass_mongocryptd_shared_library",

0 commit comments

Comments
 (0)