예제 #1
0
        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);
        }
예제 #6
0
        // 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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        /// <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();
        }