private async Task ProcessNeedKmsStateAsync(CryptContext context, CancellationToken cancellationToken)
        {
            var requests = context.GetKmsMessageRequests();

            foreach (var request in requests)
            {
                await SendKmsRequestAsync(request, cancellationToken).ConfigureAwait(false);
            }
            requests.MarkDone();
        }
        private void ProcessNeedKmsState(CryptContext context, CancellationToken cancellationToken)
        {
            var requests = context.GetKmsMessageRequests();

            foreach (var request in requests)
            {
                SendKmsRequest(request, cancellationToken);
            }
            requests.MarkDone();
        }
Beispiel #3
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);
        }
        /// <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();
        }