[CSHARP-3123] 64-bit IIS Express cannot load mongocrypt.dll Created: 02/Jun/20  Updated: 08/Jun/20  Resolved: 08/Jun/20

Status: Closed
Project: C# Driver
Component/s: Field Level Encryption
Affects Version/s: 2.10.4
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Alex Bevilacqua Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Case:

 Description   

Steps to reproduce (using Visual Studio 2019 and a local MongoDB 4.2-ent cluster)

1 - Create an ASP.NET Web Application / Web API project
2 - Enable Tools > Options > Project and Solutions > Web Projects and check the option > "Use the 64 bit version of IIS Express for web sites and projects"
3 - Set the project's Platform Target to x64
3 - Using the NuGet Package Manager, install MongoDB.Driver (2.10.4) and MongoDB.Libmongocrypt (1.0.0)
4 - Copy the following code to Controllers\ValuesController.cs:

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Encryption;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web.Http;
 
namespace WebApplication1.Controllers
{
    public class ValuesController : ApiController
    {
        private MongoClient GetCSFLEClient()
        {
            var localMasterKey = Convert.FromBase64String("Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk");
 
            var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
            var localKey = new Dictionary<string, object>
            {
                { "key", localMasterKey }
            };
            kmsProviders.Add("local", localKey);
 
            var keyVaultNamespace = CollectionNamespace.FromFullName("admin.datakeys");
            var keyVaultMongoClient = new MongoClient();
            var clientEncryptionSettings = new ClientEncryptionOptions(
                keyVaultMongoClient,
                keyVaultNamespace,
                kmsProviders);
 
            var clientEncryption = new ClientEncryption(clientEncryptionSettings);
            var dataKeyId = clientEncryption.CreateDataKey("local", new DataKeyOptions(), CancellationToken.None);
            var base64DataKeyId = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));
            clientEncryption.Dispose();
            var schemaMap = $@"{{
                properties: {{
                    encryptedField: {{
                        encrypt: {{
                            keyId: [{{
                                '$binary' : {{
                                    'base64' : '{base64DataKeyId}',
                                    'subType' : '04'
                                }}
                            }}],
                        bsonType: 'string',
                        algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
                        }}
                    }}
                }},
                'bsonType': 'object'
            }}";
 
            var collectionNamespace = CollectionNamespace.FromFullName("test.coll");
 
            var autoEncryptionSettings = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                schemaMap: new Dictionary<string, BsonDocument>()
                {
                { collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) }
                });
 
            var clientSettings = new MongoClientSettings
            {
                AutoEncryptionOptions = autoEncryptionSettings
            };
 
            return new MongoClient(clientSettings);
        }
 
        // GET api/values
        public IEnumerable<string> Get(bool csfle)
        {
            var client = (csfle) ? GetCSFLEClient() : new MongoClient();
            var database = client.GetDatabase("test");
            database.DropCollection("coll");
            var collection = database.GetCollection<BsonDocument>("coll");
 
            collection.InsertOne(new BsonDocument("encryptedField", "123456789"));
 
            var result = collection.Find(FilterDefinition<BsonDocument>.Empty).First();
 
            return new string[] { result.ToJson() };
        }
    }
}

5 - Build / Run

Using the following should succeed:

https://localhost:44373/api/Values?csfle=false

<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<string>{ "_id" : ObjectId("5ed63b324eecb9086ccccaf2"), "encryptedField" : "123456789" }</string>
</ArrayOfstring>

Using the following should fail:
https://localhost:44373/api/Values?csfle=true

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Could not find: mongocrypt.dll -- Tried: C:\Users\Administrator\AppData\Local\Temp\Temporary ASP.NET Files\vs\85bbc5a0\ab21fb48\assembly\dl3\cd3d81d3\009d89cc_8b9ad501\..\..\x64\native\windows\mongocrypt.dll,C:\Users\Administrator\AppData\Local\Temp\Temporary ASP.NET Files\vs\85bbc5a0\ab21fb48\assembly\dl3\cd3d81d3\009d89cc_8b9ad501\mongocrypt.dll
</ExceptionMessage>
<ExceptionType>System.IO.FileNotFoundException</ExceptionType>
<StackTrace>
at MongoDB.Libmongocrypt.LibraryLoader.FindLibrary(IList`1 basePaths, String[] suffixPaths, String library) at MongoDB.Libmongocrypt.LibraryLoader..ctor() at MongoDB.Libmongocrypt.Library.<>c.<.cctor>b__0_46() at System.Lazy`1.CreateValue() at System.Lazy`1.LazyInitValue() at MongoDB.Libmongocrypt.Library.<>c.<.cctor>b__0_1() at System.Lazy`1.CreateValue() at System.Lazy`1.LazyInitValue() at MongoDB.Libmongocrypt.CryptClientFactory.Create(CryptOptions options) at MongoDB.Driver.Core.Clusters.CryptClientCreator.CreateCryptClient(IReadOnlyDictionary`2 kmsProviders, IReadOnlyDictionary`2 schemaMap) at MongoDB.Driver.Encryption.ClientEncryption..ctor(ClientEncryptionOptions clientEncryptionOptions) at WebApplication1.Controllers.ValuesController.GetCSFLEClient() in C:\Users\Administrator\source\repos\WebApplication1\WebApplication1\Controllers\ValuesController.cs:line 32 at WebApplication1.Controllers.ValuesController.Get(Boolean csfle) in C:\Users\Administrator\source\repos\WebApplication1\WebApplication1\Controllers\ValuesController.cs:line 75 at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
</StackTrace>
</Error>



 Comments   
Comment by Alex Bevilacqua [ 02/Jun/20 ]

vincent.kam / dmitry.lukyanov:

Changing System.Web.Configuration.HostingEnvironmentSection.ShadowCopyBinAssemblies to false actually seems to have fixed this.

I did this in my app's Web.config using:

<configuration>
  <system.web>
    <hostingEnvironment shadowCopyBinAssemblies="false" />
  </system.web>
</configuration>

Generated at Wed Feb 07 21:44:26 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.