private async Task ProcessNeedMongoMarkingsStateAsync(CryptContext context, string databaseName, CancellationToken cancellationToken) { var database = _mongocryptdClient.GetDatabase(databaseName); var commandBytes = context.GetOperation().ToArray(); var commandDocument = new RawBsonDocument(commandBytes); var command = new BsonDocumentCommand <BsonDocument>(commandDocument); BsonDocument response = null; for (var attempt = 1; response == null; attempt++) { try { response = await database.RunCommandAsync(command, cancellationToken : cancellationToken).ConfigureAwait(false); } catch (TimeoutException) when(attempt == 1) { _mongocryptdFactory.SpawnMongocryptdProcessIfRequired(); await WaitForMongocryptdReadyAsync().ConfigureAwait(false); } } RestoreDbNodeInResponse(commandDocument, response); FeedResult(context, response); }
private void ProcessNeedMongoKeysState(CryptContext context, CancellationToken cancellationToken) { var filterBytes = context.GetOperation().ToArray(); var filterDocument = new RawBsonDocument(filterBytes); var filter = new BsonDocumentFilterDefinition <BsonDocument>(filterDocument); var cursor = _keyVaultCollection.Value.FindSync(filter, cancellationToken: cancellationToken); var results = cursor.ToList(cancellationToken); FeedResults(context, results); }
private async Task ProcessNeedMongoKeysStateAsync(CryptContext context, CancellationToken cancellationToken) { var filterBytes = context.GetOperation().ToArray(); var filterDocument = new RawBsonDocument(filterBytes); var filter = new BsonDocumentFilterDefinition <BsonDocument>(filterDocument); var cursor = await _keyVaultCollection.Value.FindAsync(filter, cancellationToken : cancellationToken).ConfigureAwait(false); var results = await cursor.ToListAsync(cancellationToken).ConfigureAwait(false); FeedResults(context, results); }
// private methods private void ProcessNeedCollectionInfoState(CryptContext context, string databaseName, CancellationToken cancellationToken) { var database = _client.GetDatabase(databaseName); var filterBytes = context.GetOperation().ToArray(); var filterDocument = new RawBsonDocument(filterBytes); var filter = new BsonDocumentFilterDefinition <BsonDocument>(filterDocument); var options = new ListCollectionsOptions { Filter = filter }; var cursor = database.ListCollections(options, cancellationToken); var results = cursor.ToList(cancellationToken); FeedResults(context, results); }
private async Task ProcessNeedCollectionInfoStateAsync(CryptContext context, string databaseName, CancellationToken cancellationToken) { var database = _client.GetDatabase(databaseName); var filterBytes = context.GetOperation().ToArray(); var filterDocument = new RawBsonDocument(filterBytes); var filter = new BsonDocumentFilterDefinition <BsonDocument>(filterDocument); var options = new ListCollectionsOptions { Filter = filter }; var cursor = await database.ListCollectionsAsync(options, cancellationToken).ConfigureAwait(false); var results = await cursor.ToListAsync(cancellationToken).ConfigureAwait(false); FeedResults(context, results); }
// private methods private void ProcessNeedCollectionInfoState(CryptContext context, string databaseName, CancellationToken cancellationToken) { if (_metadataClient == null) { // should not be reached throw new InvalidOperationException("Metadata client is null."); } var database = _metadataClient.GetDatabase(databaseName); var filterBytes = context.GetOperation().ToArray(); var filterDocument = new RawBsonDocument(filterBytes); var filter = new BsonDocumentFilterDefinition <BsonDocument>(filterDocument); var options = new ListCollectionsOptions { Filter = filter }; var cursor = database.ListCollections(options, cancellationToken); var results = cursor.ToList(cancellationToken); FeedResults(context, results); }
private BsonDocument ProcessState(CryptContext context, IMongoDatabase db, BsonDocument cmd) { BsonDocument ret = cmd; while (!context.IsDone) { Console.WriteLine("\n----------------------------------\nState:" + context.State); switch (context.State) { case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO: { var binary = context.GetOperation(); var doc = BsonUtil.ToDocument(binary); Console.WriteLine("ListCollections Query: " + doc); ListCollectionsOptions opts = new ListCollectionsOptions() { Filter = new BsonDocumentFilterDefinition <BsonDocument>(doc) }; var reply = db.ListCollections(opts); var replyDocs = reply.ToList <BsonDocument>(); Console.WriteLine("ListCollections Reply: " + replyDocs); foreach (var replyDoc in replyDocs) { Console.WriteLine("ListCollections Reply: " + replyDoc); context.Feed(BsonUtil.ToBytes(replyDoc)); } context.MarkDone(); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: { var binary = context.GetOperation(); var commandWithSchema = BsonUtil.ToDocument(binary); Console.WriteLine("MongoCryptD Query: " + commandWithSchema); var cryptDB = _clientCryptD.GetDatabase(db.DatabaseNamespace.DatabaseName); var reply = cryptDB.RunCommand(new BsonDocumentCommand <BsonDocument>(commandWithSchema)); Console.WriteLine("MongoCryptD Reply: " + reply); context.Feed(BsonUtil.ToBytes(reply)); context.MarkDone(); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS: { var binary = context.GetOperation(); Console.WriteLine("Buffer:" + BitConverter.ToString(binary.ToArray())); var doc = BsonUtil.ToDocument(binary); Console.WriteLine("GetKeys Query: " + doc); var reply = _keyVault.Find(new BsonDocumentFilterDefinition <BsonDocument>(doc)); var replyDocs = reply.ToList <BsonDocument>(); Console.WriteLine("GetKeys Reply: " + replyDocs); foreach (var replyDoc in replyDocs) { context.Feed(BsonUtil.ToBytes(replyDoc)); } context.MarkDone(); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS: { var requests = context.GetKmsMessageRequests(); foreach (var req in requests) { DoKmsRequest(req); } requests.MarkDone(); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_READY: { Binary b = context.FinalizeForEncryption(); Console.WriteLine("Buffer:" + BitConverter.ToString(b.ToArray())); ret = BsonUtil.ToDocument(b); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_DONE: { Console.WriteLine("DONE!!"); return(ret); } case CryptContext.StateCode.MONGOCRYPT_CTX_ERROR: { throw new NotImplementedException(); } } } return(ret); }
/// <summary> /// Processes the current state, simulating the execution the operation/post requests needed to reach the next state /// Returns (stateProcessed, binaryOperationProduced, bsonOperationProduced) /// </summary> /// <exception cref="NotImplementedException"></exception> private (CryptContext.StateCode stateProcessed, Binary binaryProduced, BsonDocument bsonOperationProduced) ProcessState(CryptContext context, bool isKmsDecrypt = true) { _output.WriteLine("\n----------------------------------\nState:" + context.State); switch (context.State) { case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO: { var binary = context.GetOperation(); var doc = BsonUtil.ToDocument(binary); _output.WriteLine("ListCollections: " + doc); var reply = ReadJsonTestFile("collection-info.json"); _output.WriteLine("Reply:" + reply); context.Feed(BsonUtil.ToBytes(reply)); context.MarkDone(); return(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO, binary, doc); } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: { var binary = context.GetOperation(); var doc = BsonUtil.ToDocument(binary); _output.WriteLine("Markings: " + doc); var reply = ReadJsonTestFile("mongocryptd-reply.json"); _output.WriteLine("Reply:" + reply); context.Feed(BsonUtil.ToBytes(reply)); context.MarkDone(); return(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS, binary, doc); } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS: { var binary = context.GetOperation(); var doc = BsonUtil.ToDocument(binary); _output.WriteLine("Key Document: " + doc); var reply = ReadJsonTestFile("key-document.json"); _output.WriteLine("Reply:" + reply); context.Feed(BsonUtil.ToBytes(reply)); context.MarkDone(); return(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS, binary, doc); } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS: { var requests = context.GetKmsMessageRequests(); foreach (var req in requests) { var binary = req.Message; _output.WriteLine("Key Document: " + binary); var postRequest = binary.ToString(); // TODO: add different hosts handling postRequest.Should().Contain("Host:kms.us-east-1.amazonaws.com"); // only AWS var reply = ReadHttpTestFile(isKmsDecrypt ? "kms-decrypt-reply.txt" : "kms-encrypt-reply.txt"); _output.WriteLine("Reply: " + reply); req.Feed(Encoding.UTF8.GetBytes(reply)); req.BytesNeeded.Should().Be(0); } requests.MarkDone(); return(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS, null, null); } case CryptContext.StateCode.MONGOCRYPT_CTX_READY: { Binary binary = context.FinalizeForEncryption(); _output.WriteLine("Buffer:" + binary.ToArray()); var document = BsonUtil.ToDocument(binary); _output.WriteLine("Document:" + document); return(CryptContext.StateCode.MONGOCRYPT_CTX_READY, binary, document); } case CryptContext.StateCode.MONGOCRYPT_CTX_DONE: { _output.WriteLine("DONE!!"); return(CryptContext.StateCode.MONGOCRYPT_CTX_DONE, null, null); } case CryptContext.StateCode.MONGOCRYPT_CTX_ERROR: { // We expect exceptions are thrown before we get to this state throw new NotImplementedException(); } } throw new NotImplementedException(); }