-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
We are using manual mongo field level encryption with automatic decryption.
Starting in go mongo driver 1.5.1 we get this error on decryption: "key vault communication error: session was not created by this client"
To reproduce, I have taken the go mongo driver example
Test_Example_explictEncryptionWithAutomaticDecryption and modified it to use a session (instead of empty context):
// code placeholder //taken from mongo_driver 1.5.1 func Test_Example_explictEncryptionWithAutomaticDecryption(t *testing.T) { // Automatic encryption requires MongoDB 4.2 enterprise, but automatic decryption is supported for all users. //var localMasterKey []byte // This must be the same master key that was used to create the encryption key. kmsProviders := map[string]map[string]interface{}{ "local": { "key": fakeKey, }, } // The MongoDB namespace (db.collection) used to store the encryption data keys. keyVaultDBName, keyVaultCollName := "encryption", "testKeyVault" keyVaultNamespace := keyVaultDBName + "." + keyVaultCollName // Create the Client for reading/writing application data. Configure it with BypassAutoEncryption=true to disable // automatic encryption but keep automatic decryption. Setting BypassAutoEncryption will also bypass spawning // mongocryptd in the driver. autoEncryptionOpts := options.AutoEncryption(). SetKmsProviders(kmsProviders). SetKeyVaultNamespace(keyVaultNamespace). SetBypassAutoEncryption(true) clientOpts := options.Client(). ApplyURI("mongodb://localhost:27017"). SetAutoEncryptionOptions(autoEncryptionOpts) client, err := mongo.Connect(context.TODO(), clientOpts) if err != nil { panic(err) } defer func() { _ = client.Disconnect(context.TODO()) }() // Get a handle to the application collection and clear existing data. coll := client.Database("test").Collection("coll") _ = coll.Drop(context.TODO()) // Set up the key vault for this example. keyVaultColl := client.Database(keyVaultDBName).Collection(keyVaultCollName) _ = keyVaultColl.Drop(context.TODO()) // Ensure that two data keys cannot share the same keyAltName. keyVaultIndex := mongo.IndexModel{ Keys: bson.D{{"keyAltNames", 1}}, Options: options.Index(). SetUnique(true). SetPartialFilterExpression(bson.D{ {"keyAltNames", bson.D{ {"$exists", true}, }}, }), } if _, err = keyVaultColl.Indexes().CreateOne(context.TODO(), keyVaultIndex); err != nil { panic(err) } // Create the ClientEncryption object to use for explicit encryption/decryption. The Client passed to // NewClientEncryption is used to read/write to the key vault. This can be the same Client used by the main // application. clientEncryptionOpts := options.ClientEncryption(). SetKmsProviders(kmsProviders). SetKeyVaultNamespace(keyVaultNamespace) clientEncryption, err := mongo.NewClientEncryption(client, clientEncryptionOpts) if err != nil { panic(err) } defer func() { _ = clientEncryption.Close(context.TODO()) }() // Create a new data key for the encrypted field. dataKeyOpts := options.DataKey().SetKeyAltNames([]string{"go_encryption_example"}) dataKeyID, err := clientEncryption.CreateDataKey(context.TODO(), "local", dataKeyOpts) if err != nil { panic(err) } // Create a bson.RawValue to encrypt and encrypt it using the key that was just created. rawValueType, rawValueData, err := bson.MarshalValue("123456789") if err != nil { panic(err) } rawValue := bson.RawValue{Type: rawValueType, Value: rawValueData} encryptionOpts := options.Encrypt(). SetAlgorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"). SetKeyID(dataKeyID) encryptedField, err := clientEncryption.Encrypt(context.TODO(), rawValue, encryptionOpts) if err != nil { panic(err) } // Insert a document with the encrypted field and then find it. The FindOne call will automatically decrypt the // field in the document. if _, err = coll.InsertOne(context.TODO(), bson.D{{"encryptedField", encryptedField}}); err != nil { panic(err) } var foundDoc bson.M //if err = coll.FindOne(context.TODO(), bson.D{}).Decode(&foundDoc); err != nil { // panic(err) //} //fmt.Printf("Decrypted document: %v\n", foundDoc) ctx := context.Background() err = client.UseSessionWithOptions(ctx, nil, func(sessionContext mongo.SessionContext) error { //sess if err = coll.FindOne(sessionContext, bson.D{}).Decode(&foundDoc); err != nil { panic(err) } fmt.Printf("Decrypted document: %v\n", foundDoc) return nil }) }
This throws error "key vault communication error: session was not created by this client".
When going back to driver 1.5.0-beta1, things work because if
SetKeyVaultClientOptions are not provided as part of AutoEncryption options on client creation, client is re-used for key vault communication.
When going to driver 1.5.1 (also checked 1.7.2), we get this error.
- is caused by
-
GODRIVER-1832 Sharing a MongoClient for metadata lookup can lead to deadlock in drivers using automatic encryption
- Closed
- related to
-
DRIVERS-1937 Support explicit sessions in CSFLE auto encryption internal commands
- Backlog