Example #1
0
        public void ClientSideEncryptionSimpleTour()
        {
            RequireServer.Check().Supports(Feature.ClientSideEncryption);

            var localMasterKey = Convert.FromBase64String(LocalMasterKey);

            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 autoEncryptionOptions = new AutoEncryptionOptions(keyVaultNamespace, kmsProviders);

            var mongoClientSettings = new MongoClientSettings
            {
                AutoEncryptionOptions = autoEncryptionOptions
            };
            var client   = new MongoClient(mongoClientSettings);
            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();

            _output.WriteLine(result.ToJson());
        }
Example #2
0
        private DisposableMongoClient CreateMongoClient(
            CollectionNamespace keyVaultNamespace = null,
            BsonDocument schemaMapDocument        = null,
            IReadOnlyDictionary <string, IReadOnlyDictionary <string, object> > kmsProviders = null,
            bool withExternalKeyVault = false,
            Action <ClusterBuilder> clusterConfigurator = null,
            Dictionary <string, object> extraOptions    = null,
            bool bypassAutoEncryption = false)
        {
            var mongoClientSettings = DriverTestConfiguration.GetClientSettings().Clone();

#pragma warning disable 618
            if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2)
            {
                mongoClientSettings.GuidRepresentation = GuidRepresentation.Unspecified;
            }
#pragma warning restore 618
            mongoClientSettings.ClusterConfigurator = clusterConfigurator;

            if (keyVaultNamespace != null || schemaMapDocument != null || kmsProviders != null || withExternalKeyVault)
            {
                if (extraOptions == null)
                {
                    extraOptions = new Dictionary <string, object>()
                    {
                        { "mongocryptdSpawnPath", Environment.GetEnvironmentVariable("MONGODB_BINARIES") ?? string.Empty }
                    };
                }

                var schemaMap = GetSchemaMapIfNotNull(schemaMapDocument);

                if (kmsProviders == null)
                {
                    kmsProviders = new ReadOnlyDictionary <string, IReadOnlyDictionary <string, object> >(new Dictionary <string, IReadOnlyDictionary <string, object> >());
                }

                var autoEncryptionOptions = new AutoEncryptionOptions(
                    keyVaultNamespace: keyVaultNamespace,
                    kmsProviders: kmsProviders,
                    schemaMap: schemaMap,
                    extraOptions: extraOptions,
                    bypassAutoEncryption: bypassAutoEncryption);

                if (withExternalKeyVault)
                {
                    var externalKeyVaultClientSettings = DriverTestConfiguration.GetClientSettings().Clone();
                    externalKeyVaultClientSettings.Credential = MongoCredential.FromComponents(null, null, "fake-user", "fake-pwd");
                    var externalKeyVaultClient = new MongoClient(externalKeyVaultClientSettings);
                    autoEncryptionOptions = autoEncryptionOptions.With(keyVaultClient: externalKeyVaultClient);
                }
                mongoClientSettings.AutoEncryptionOptions = autoEncryptionOptions;
            }

            return(new DisposableMongoClient(new MongoClient(mongoClientSettings)));
        }
        // private methods
        private AutoEncryptionOptions ConfigureAutoEncryptionOptions(BsonDocument autoEncryptOpts)
        {
            var extraOptions = new Dictionary <string, object>();

            EncryptionTestHelper.ConfigureDefaultExtraOptions(extraOptions);

            var kmsProviders          = new ReadOnlyDictionary <string, IReadOnlyDictionary <string, object> >(new Dictionary <string, IReadOnlyDictionary <string, object> >());
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace: __keyVaultCollectionNamespace,
                kmsProviders: kmsProviders,
                extraOptions: extraOptions);

            foreach (var option in autoEncryptOpts.Elements)
            {
                switch (option.Name)
                {
                case "kmsProviders":
                    kmsProviders          = ParseKmsProviders(option.Value.AsBsonDocument);
                    autoEncryptionOptions = autoEncryptionOptions.With(kmsProviders: kmsProviders);
                    var tlsSettings = EncryptionTestHelper.CreateTlsOptionsIfAllowed(kmsProviders, allowClientCertificateFunc: (kms) => kms == "kmip");
                    if (tlsSettings != null)
                    {
                        autoEncryptionOptions = autoEncryptionOptions.With(tlsOptions: tlsSettings);
                    }
                    break;

                case "schemaMap":
                    var schemaMapsDocument = option.Value.AsBsonDocument;
                    var schemaMaps         = schemaMapsDocument.Elements.ToDictionary(e => e.Name, e => e.Value.AsBsonDocument);
                    autoEncryptionOptions = autoEncryptionOptions.With(schemaMap: schemaMaps);
                    break;

                case "bypassAutoEncryption":
                    autoEncryptionOptions = autoEncryptionOptions.With(bypassAutoEncryption: option.Value.ToBoolean());
                    break;

                case "keyVaultNamespace":
                    autoEncryptionOptions = autoEncryptionOptions.With(keyVaultNamespace: CollectionNamespace.FromFullName(option.Value.AsString));
                    break;

                case "encryptedFieldsMap":
                    var encryptedFieldsMapDocument = option.Value.AsBsonDocument;
                    var encryptedFieldsMap         = encryptedFieldsMapDocument.Elements.ToDictionary(e => e.Name, e => e.Value.AsBsonDocument);
                    autoEncryptionOptions = autoEncryptionOptions.With(encryptedFieldsMap: encryptedFieldsMap);
                    break;

                default:
                    throw new Exception($"Unexpected auto encryption option {option.Name}.");
                }
            }

            return(autoEncryptionOptions);
        }
Example #4
0
        public void ToString_should_return_expected_result()
        {
            var guid      = new Guid("00112233445566778899aabbccddeeff");
            var guidBytes = GuidConverter.ToBytes(guid, GuidRepresentation.Standard);
            var binary    = new BsonBinaryData(guidBytes, BsonBinarySubType.UuidStandard);

            var extraOptions = new Dictionary <string, object>()
            {
                { "mongocryptdURI", "testURI" },
            };
            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >()
            {
                { "provider1", new Dictionary <string, object>()
                  {
                      { "string", "test" }
                  } },
                { "provider2", new Dictionary <string, object>()
                  {
                      { "binary", binary.Bytes }
                  } }
            };
            var schemaMap = new Dictionary <string, BsonDocument>()
            {
                { "coll1", new BsonDocument("string", "test") },
                { "coll2", new BsonDocument("binary", binary) },
            };
            var tlsOptions = new Dictionary <string, SslSettings>
            {
                { "local", new SslSettings {
                      ClientCertificates = new [] { Mock.Of <X509Certificate2>() }
                  } }
            };
            var encryptedFieldsMap = new Dictionary <string, BsonDocument>
            {
                {
                    "db.test",
                    BsonDocument.Parse("{ dummy : 'doc' }")
                }
            };

            var subject = new AutoEncryptionOptions(
                keyVaultNamespace: __keyVaultNamespace,
                kmsProviders: kmsProviders,
                bypassAutoEncryption: true,
                extraOptions: extraOptions,
                schemaMap: schemaMap,
                tlsOptions: tlsOptions,
                encryptedFieldsMap: encryptedFieldsMap);

            var result = subject.ToString();

            result.Should().Be("{ BypassAutoEncryption : True, KmsProviders : { \"provider1\" : { \"string\" : \"test\" }, \"provider2\" : { \"binary\" : { \"_t\" : \"System.Byte[]\", \"_v\" : new BinData(0, \"ABEiM0RVZneImaq7zN3u/w==\") } } }, KeyVaultNamespace : \"db.coll\", ExtraOptions : { \"mongocryptdURI\" : \"testURI\" }, SchemaMap : { \"coll1\" : { \"string\" : \"test\" }, \"coll2\" : { \"binary\" : UUID(\"00112233-4455-6677-8899-aabbccddeeff\") } }, TlsOptions: [{ \"local\" : \"<hidden>\" }], EncryptedFieldsMap : { \"db.test\" : { \"dummy\" : \"doc\" } } }");
        }
Example #5
0
        // private methods
        private AutoEncryptionOptions ConfigureAutoEncryptionOptions(BsonDocument autoEncryptOpts)
        {
            var keyVaultCollectionNamespace = new CollectionNamespace("admin", "datakeys");
            var extraOptions = new Dictionary <string, object>()
            {
                { "mongocryptdSpawnPath", Environment.GetEnvironmentVariable("MONGODB_BINARIES") ?? string.Empty }
            };

            var kmsProviders          = new ReadOnlyDictionary <string, IReadOnlyDictionary <string, object> >(new Dictionary <string, IReadOnlyDictionary <string, object> >());
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace: keyVaultCollectionNamespace,
                kmsProviders: kmsProviders,
                extraOptions: extraOptions);

            foreach (var option in autoEncryptOpts.Elements)
            {
                switch (option.Name)
                {
                case "kmsProviders":
                    kmsProviders          = ParseKmsProviders(option.Value.AsBsonDocument);
                    autoEncryptionOptions = autoEncryptionOptions
                                            .With(kmsProviders: kmsProviders);
                    break;

                case "schemaMap":
                    var schemaMaps         = new Dictionary <string, BsonDocument>();
                    var schemaMapsDocument = option.Value.AsBsonDocument;
                    foreach (var schemaMapElement in schemaMapsDocument.Elements)
                    {
                        schemaMaps.Add(schemaMapElement.Name, schemaMapElement.Value.AsBsonDocument);
                    }
                    autoEncryptionOptions = autoEncryptionOptions.With(schemaMap: schemaMaps);
                    break;

                case "bypassAutoEncryption":
                    autoEncryptionOptions = autoEncryptionOptions.With(bypassAutoEncryption: option.Value.ToBoolean());
                    break;

                case "keyVaultNamespace":
                    autoEncryptionOptions = autoEncryptionOptions.With(keyVaultNamespace: CollectionNamespace.FromFullName(option.Value.AsString));
                    break;

                default:
                    throw new Exception($"Unexpected auto encryption option {option.Name}.");
                }
            }

            return(autoEncryptionOptions);
        }
        // constructors
        /// <summary>
        /// Creates a new instance of MongoClientSettings. Usually you would use a connection string instead.
        /// </summary>
        public MongoClientSettings()
        {
            _allowInsecureTls = false;
            _applicationName = null;
            _autoEncryptionOptions = null;
            _compressors = new CompressorConfiguration[0];
#pragma warning disable CS0618 // Type or member is obsolete
            _connectionMode = ConnectionMode.Automatic;
            _connectionModeSwitch = ConnectionModeSwitch.NotSet;
#pragma warning restore CS0618 // Type or member is obsolete
            _connectTimeout = MongoDefaults.ConnectTimeout;
            _credentials = new MongoCredentialStore(new MongoCredential[0]);
            _directConnection = null;
#pragma warning disable 618
            if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2)
            {
                _guidRepresentation = MongoDefaults.GuidRepresentation;
            }
#pragma warning restore 618
            _heartbeatInterval = ServerSettings.DefaultHeartbeatInterval;
            _heartbeatTimeout = ServerSettings.DefaultHeartbeatTimeout;
            _ipv6 = false;
            _localThreshold = MongoDefaults.LocalThreshold;
            _maxConnectionIdleTime = MongoDefaults.MaxConnectionIdleTime;
            _maxConnectionLifeTime = MongoDefaults.MaxConnectionLifeTime;
            _maxConnectionPoolSize = MongoDefaults.MaxConnectionPoolSize;
            _minConnectionPoolSize = MongoDefaults.MinConnectionPoolSize;
            _readConcern = ReadConcern.Default;
            _readEncoding = null;
            _readPreference = ReadPreference.Primary;
            _replicaSetName = null;
            _retryReads = true;
            _retryWrites = true;
            _scheme = ConnectionStringScheme.MongoDB;
            _sdamLogFilename = null;
            _servers = new List<MongoServerAddress> { new MongoServerAddress("localhost") };
            _serverSelectionTimeout = MongoDefaults.ServerSelectionTimeout;
            _socketTimeout = MongoDefaults.SocketTimeout;
            _sslSettings = null;
            _useTls = false;
#pragma warning disable 618
            _waitQueueSize = MongoDefaults.ComputedWaitQueueSize;
#pragma warning restore 618
            _waitQueueTimeout = MongoDefaults.WaitQueueTimeout;
            _writeConcern = WriteConcern.Acknowledged;
            _writeEncoding = null;
        }
        private IMongoClient CreateAutoEncryptingClient(
            KmsKeyLocation kmsKeyLocation,
            CollectionNamespace keyVaultNamespace,
            BsonDocument schema)
        {
            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >();

            // Specify the local master encryption key
            if (kmsKeyLocation == KmsKeyLocation.Local)
            {
                var localMasterKeyBase64 = File.ReadAllText(__localMasterKeyPath);
                var localMasterKeyBytes  = Convert.FromBase64String(localMasterKeyBase64);
                var localOptions         = new Dictionary <string, object>
                {
                    { "key", localMasterKeyBytes }
                };
                kmsProviders.Add("local", localOptions);
            }

            //
            var schemaMap = new Dictionary <string, BsonDocument>();

            schemaMap.Add(_medicalRecordsNamespace.ToString(), schema);

            // Specify location of mongocryptd binary, if necessary
            var extraOptions = new Dictionary <string, object>()
            {
                // uncomment the following line if you are running mongocryptd manually
                // { "mongocryptdBypassSpawn", true }
            };

            // Create CSFLE-enabled MongoClient
            // The addition of the automatic encryption settings are what
            // change this from a standard MongoClient to a CSFLE-enabled one
            var clientSettings        = MongoClientSettings.FromConnectionString(_connectionString);
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace: keyVaultNamespace,
                kmsProviders: kmsProviders,
                schemaMap: schemaMap,
                extraOptions: extraOptions);

            clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
            return(new MongoClient(clientSettings));
        }
Example #8
0
        public void Equals_should_work_correctly()
        {
            var options1 = CreateAutoEncryptionOptions();
            var options2 = CreateAutoEncryptionOptions();

            options1.Equals(options2).Should().BeTrue();

            options1 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options2 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeTrue();

            options1 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options2 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings(), collectionNamespace: CollectionNamespace.FromFullName("d.c"));
            options1.Equals(options2).Should().BeFalse();

            options1 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings(), tlsKey: "test1");
            options2 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeFalse();

            options1 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings()
            {
                EnabledSslProtocols = System.Security.Authentication.SslProtocols.None
            });
            options2 = CreateAutoEncryptionOptions(tlsOptions: new SslSettings());
            options1.Equals(options2).Should().BeFalse();

            AutoEncryptionOptions CreateAutoEncryptionOptions(SslSettings tlsOptions = null, string tlsKey = "test", CollectionNamespace collectionNamespace = null)
            {
                var autoEncryptionOptions = new AutoEncryptionOptions(
                    keyVaultNamespace: collectionNamespace ?? __keyVaultNamespace,
                    kmsProviders: GetKmsProviders());

                if (tlsOptions != null)
                {
                    autoEncryptionOptions = autoEncryptionOptions.With(tlsOptions: new Dictionary <string, SslSettings> {
                        { tlsKey, tlsOptions }
                    });
                }
                return(autoEncryptionOptions);
            }
        }
Example #9
0
        public void ToString_should_return_expected_result()
        {
            var guid      = new Guid("00112233445566778899aabbccddeeff");
            var guidBytes = GuidConverter.ToBytes(guid, GuidRepresentation.Standard);
            var binary    = new BsonBinaryData(guidBytes, BsonBinarySubType.UuidStandard);

            var extraOptions = new Dictionary <string, object>()
            {
                { "mongocryptdURI", "testURI" },
            };
            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >()
            {
                { "provider1", new Dictionary <string, object>()
                  {
                      { "string", "test" }
                  } },
                { "provider2", new Dictionary <string, object>()
                  {
                      { "binary", binary.Bytes }
                  } }
            };
            var schemaMap = new Dictionary <string, BsonDocument>()
            {
                { "coll1", new BsonDocument("string", "test") },
                { "coll2", new BsonDocument("binary", binary) },
            };

            var subject = new AutoEncryptionOptions(
                keyVaultNamespace: CollectionNamespace.FromFullName("db.coll"),
                kmsProviders: kmsProviders,
                bypassAutoEncryption: true,
                extraOptions: extraOptions,
                schemaMap: schemaMap);

            var result = subject.ToString();

            result.Should().Be("{ BypassAutoEncryption : True, KmsProviders : { \"provider1\" : { \"string\" : \"test\" }, \"provider2\" : { \"binary\" : { \"_t\" : \"System.Byte[]\", \"_v\" : new BinData(0, \"ABEiM0RVZneImaq7zN3u/w==\") } } }, KeyVaultNamespace : \"db.coll\", ExtraOptions : { \"mongocryptdURI\" : \"testURI\" }, SchemaMap : { \"coll1\" : { \"string\" : \"test\" }, \"coll2\" : { \"binary\" : UUID(\"00112233-4455-6677-8899-aabbccddeeff\") } } }");
        }
        private DisposableMongoClient GetClient(bool withAutoEncryption = false, Dictionary <string, object> extraOptions = null)
        {
            var mongoClientSettings = new MongoClientSettings();

            if (withAutoEncryption)
            {
                if (extraOptions == null)
                {
                    extraOptions = new Dictionary <string, object>();
                }

                EncryptionTestHelper.ConfigureDefaultExtraOptions(extraOptions);

                var kmsProviders          = GetKmsProviders();
                var autoEncryptionOptions = new AutoEncryptionOptions(
                    keyVaultNamespace: __keyVaultCollectionNamespace,
                    kmsProviders: kmsProviders,
                    extraOptions: extraOptions);
                mongoClientSettings.AutoEncryptionOptions = autoEncryptionOptions;
            }

            return(new DisposableMongoClient(new MongoClient(mongoClientSettings), CreateLogger <DisposableMongoClient>()));
        }
Example #11
0
        private AutoEncryptionOptions CreateSubject(
            SslSettings tlsOptions = null,
            string tlsKey          = "test",
            CollectionNamespace collectionNamespace              = null,
            Dictionary <string, BsonDocument> schemaMap          = null,
            Dictionary <string, BsonDocument> encryptedFieldsMap = null,
            Dictionary <string, object> extraOptions             = null)
        {
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace: collectionNamespace ?? __keyVaultNamespace,
                kmsProviders: GetKmsProviders(),
                schemaMap: schemaMap,
                encryptedFieldsMap: encryptedFieldsMap,
                extraOptions: extraOptions);

            if (tlsOptions != null)
            {
                autoEncryptionOptions = autoEncryptionOptions.With(tlsOptions: new Dictionary <string, SslSettings> {
                    { tlsKey, tlsOptions }
                });
            }
            return(autoEncryptionOptions);
        }
Example #12
0
        private DisposableMongoClient GetClient(bool withAutoEncryption = false, Dictionary <string, object> extraOptions = null)
        {
            var mongoClientSettings = new MongoClientSettings();

            if (withAutoEncryption)
            {
                if (extraOptions == null)
                {
                    extraOptions = new Dictionary <string, object>()
                    {
                        { "mongocryptdSpawnPath", Environment.GetEnvironmentVariable("MONGODB_BINARIES") ?? string.Empty }
                    };
                }

                var kmsProviders          = GetKmsProviders();
                var autoEncryptionOptions = new AutoEncryptionOptions(
                    keyVaultNamespace: __keyVaultCollectionNamespace,
                    kmsProviders: kmsProviders,
                    extraOptions: extraOptions);
                mongoClientSettings.AutoEncryptionOptions = autoEncryptionOptions;
            }

            return(new DisposableMongoClient(new MongoClient(mongoClientSettings)));
        }
        // public void ClientSideEncryptionAutoEncryptionSettingsTour()
        public static void Main(string[] args)
        {
            var localMasterKey = Convert.FromBase64String(LocalMasterKey);

            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >();
            var localKey     = new Dictionary <string, object>
            {
                { "key", localMasterKey }
            };

            kmsProviders.Add("local", localKey);

            var keyVaultDB        = "keyVault";
            var keystore          = "__keystore";
            var keyVaultNamespace = CollectionNamespace.FromFullName($"{keyVaultDB}.{keystore}");

            var keyVaultMongoClient      = new MongoClient();
            var clientEncryptionSettings = new ClientEncryptionOptions(
                keyVaultMongoClient,
                keyVaultNamespace,
                kmsProviders);
            var clientEncryption = new ClientEncryption(clientEncryptionSettings);

            keyVaultMongoClient.GetDatabase(keyVaultDB).DropCollection(keystore);

            var altKeyName      = new[] { "csharpDataKey01" };
            var dataKeyOptions  = new DataKeyOptions(alternateKeyNames: altKeyName);
            var dataKeyId       = clientEncryption.CreateDataKey("local", dataKeyOptions, CancellationToken.None);
            var base64DataKeyId = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));

            clientEncryption.Dispose();

            var collectionNamespace = CollectionNamespace.FromFullName("test.coll");

            var schemaMap = $@"{{
                properties: {{
                    SSN: {{
                        encrypt: {{
                            keyId: [{{
                                '$binary' : {{
                                    'base64' : '{base64DataKeyId}',
                                    'subType' : '04'
                                }}
                            }}],
                        bsonType: 'string',
                        algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
                        }}
                    }}
                }},
                'bsonType': 'object'
            }}";
            var autoEncryptionSettings = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                schemaMap: new Dictionary <string, BsonDocument>()
            {
                { collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) }
            });
            var clientSettings = new MongoClientSettings
            {
                AutoEncryptionOptions = autoEncryptionSettings
            };
            var client   = new MongoClient(clientSettings);
            var database = client.GetDatabase("test");

            database.DropCollection("coll");

            var collection = database.GetCollection <BsonDocument>("coll");

            collection.InsertOne(new BsonDocument("SSN", "123456789"));

            var result = collection.Find(FilterDefinition <BsonDocument> .Empty).First();

            Console.WriteLine(result.ToJson());
        }
        private IMongoClient CreateAutoEncryptingClient(
            KmsKeyLocation kmsKeyLocation,
            CollectionNamespace keyVaultNamespace,
            BsonDocument schema)
        {
            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >();

            switch (kmsKeyLocation)
            {
            case KmsKeyLocation.Local:
                var localMasterKeyBase64 = File.ReadAllText(__localMasterKeyPath);
                var localMasterKeyBytes  = Convert.FromBase64String(localMasterKeyBase64);
                var localOptions         = new Dictionary <string, object>
                {
                    { "key", localMasterKeyBytes }
                };
                kmsProviders.Add("local", localOptions);
                break;

            case KmsKeyLocation.AWS:
                var awsAccessKey       = Environment.GetEnvironmentVariable("FLE_AWS_ACCESS_KEY");
                var awsSecretAccessKey = Environment.GetEnvironmentVariable("FLE_AWS_SECRET_ACCESS_KEY");
                var awsKmsOptions      = new Dictionary <string, object>
                {
                    { "accessKeyId", awsAccessKey },
                    { "secretAccessKey", awsSecretAccessKey }
                };
                kmsProviders.Add("aws", awsKmsOptions);
                break;

            case KmsKeyLocation.Azure:
                var azureTenantId                 = Environment.GetEnvironmentVariable("FLE_AZURE_TENANT_ID");
                var azureClientId                 = Environment.GetEnvironmentVariable("FLE_AZURE_CLIENT_ID");
                var azureClientSecret             = Environment.GetEnvironmentVariable("FLE_AZURE_CLIENT_SECRET");
                var azureIdentityPlatformEndpoint = Environment.GetEnvironmentVariable("FLE_AZURE_IDENTIFY_PLATFORM_ENPDOINT");     // Optional, only needed if user is using a non-commercial Azure instance

                var azureKmsOptions = new Dictionary <string, object>
                {
                    { "tenantId", azureTenantId },
                    { "clientId", azureClientId },
                    { "clientSecret", azureClientSecret },
                };
                if (azureIdentityPlatformEndpoint != null)
                {
                    azureKmsOptions.Add("identityPlatformEndpoint", azureIdentityPlatformEndpoint);
                }
                kmsProviders.Add("azure", azureKmsOptions);
                break;

            case KmsKeyLocation.GCP:
                var gcpPrivateKey = Environment.GetEnvironmentVariable("FLE_GCP_PRIVATE_KEY");
                var gcpEmail      = Environment.GetEnvironmentVariable("FLE_GCP_EMAIL");
                var gcpKmsOptions = new Dictionary <string, object>
                {
                    { "privateKey", gcpPrivateKey },
                    { "email", gcpEmail },
                };
                kmsProviders.Add("gcp", gcpKmsOptions);
                break;
            }

            var schemaMap = new Dictionary <string, BsonDocument>();

            schemaMap.Add(_medicalRecordsNamespace.ToString(), schema);

            var extraOptions = new Dictionary <string, object>()
            {
                // uncomment the following line if you are running mongocryptd manually
                // { "mongocryptdBypassSpawn", true }
            };

            var clientSettings        = MongoClientSettings.FromConnectionString(_connectionString);
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace: keyVaultNamespace,
                kmsProviders: kmsProviders,
                schemaMap: schemaMap,
                extraOptions: extraOptions);

            clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
            return(new MongoClient(clientSettings));
        }
        public void ClientSideExplicitEncryptionAndAutoDecryptionTour()
        {
            RequireServer.Check().Supports(Feature.ClientSideEncryption);

            var localMasterKey = Convert.FromBase64String(LocalMasterKey);

            var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >();
            var localKey     = new Dictionary <string, object>
            {
                { "key", localMasterKey }
            };

            kmsProviders.Add("local", localKey);

            var keyVaultNamespace     = CollectionNamespace.FromFullName("encryption.__keyVault");
            var collectionNamespace   = CollectionNamespace.FromFullName("test.coll");
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                bypassAutoEncryption: true);
            var clientSettings = MongoClientSettings.FromConnectionString("mongodb://localhost");

            clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
            var mongoClient = new MongoClient(clientSettings);
            var database    = mongoClient.GetDatabase(collectionNamespace.DatabaseNamespace.DatabaseName);

            database.DropCollection(collectionNamespace.CollectionName);
            var collection = database.GetCollection <BsonDocument>(collectionNamespace.CollectionName);

            var keyVaultClient   = new MongoClient("mongodb://localhost");
            var keyVaultDatabase = keyVaultClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.DatabaseName);

            keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName);

            // Create the ClientEncryption instance
            var clientEncryptionSettings = new ClientEncryptionOptions(
                keyVaultClient,
                keyVaultNamespace,
                kmsProviders);

            using (var clientEncryption = new ClientEncryption(clientEncryptionSettings))
            {
                var dataKeyId = clientEncryption.CreateDataKey(
                    "local",
                    new DataKeyOptions(),
                    CancellationToken.None);

                var originalString = "123456789";
                _output.WriteLine($"Original string {originalString}.");

                // Explicitly encrypt a field
                var encryptOptions = new EncryptOptions(
                    EncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic.ToString(),
                    keyId: dataKeyId);
                var encryptedFieldValue = clientEncryption.Encrypt(
                    originalString,
                    encryptOptions,
                    CancellationToken.None);
                _output.WriteLine($"Encrypted value {encryptedFieldValue}.");

                collection.InsertOne(new BsonDocument("encryptedField", encryptedFieldValue));

                // Automatically decrypts the encrypted field.
                var decryptedValue = collection.Find(FilterDefinition <BsonDocument> .Empty).First();
                _output.WriteLine($"Decrypted document {decryptedValue.ToJson()}.");
            }
        }
Example #16
0
        public void ClientSideEncryptionAutoEncryptionSettingsTour()
        {
            RequireServer.Check().Supports(Feature.ClientSideEncryption);

            var localMasterKey = Convert.FromBase64String(LocalMasterKey);

            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 collectionNamespace = CollectionNamespace.FromFullName("test.coll");

            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 autoEncryptionSettings = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                schemaMap: new Dictionary <string, BsonDocument>()
            {
                { collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) }
            });
            var clientSettings = new MongoClientSettings
            {
                AutoEncryptionOptions = autoEncryptionSettings
            };
            var client   = new MongoClient(clientSettings);
            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();

            _output.WriteLine(result.ToJson());
        }