mongo 2.11.6 → 2.12.0.rc0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -2
- data.tar.gz.sig +0 -0
- data/CONTRIBUTING.md +1 -1
- data/lib/mongo.rb +3 -0
- data/lib/mongo/address.rb +13 -2
- data/lib/mongo/auth.rb +1 -0
- data/lib/mongo/auth/credential_cache.rb +51 -0
- data/lib/mongo/auth/scram/conversation.rb +20 -16
- data/lib/mongo/auth/user.rb +0 -8
- data/lib/mongo/auth/user/view.rb +4 -4
- data/lib/mongo/background_thread.rb +1 -1
- data/lib/mongo/bulk_write.rb +5 -5
- data/lib/mongo/client.rb +126 -11
- data/lib/mongo/client_encryption.rb +103 -0
- data/lib/mongo/cluster.rb +2 -2
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +18 -6
- data/lib/mongo/cluster/sdam_flow.rb +54 -58
- data/lib/mongo/cluster/srv_monitor.rb +1 -1
- data/lib/mongo/collection.rb +3 -3
- data/lib/mongo/collection/view.rb +1 -1
- data/lib/mongo/collection/view/aggregation.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +12 -3
- data/lib/mongo/collection/view/iterable.rb +14 -5
- data/lib/mongo/collection/view/map_reduce.rb +2 -2
- data/lib/mongo/collection/view/readable.rb +7 -9
- data/lib/mongo/collection/view/writable.rb +7 -7
- data/lib/mongo/crypt.rb +33 -0
- data/lib/mongo/crypt/auto_decryption_context.rb +42 -0
- data/lib/mongo/crypt/auto_encrypter.rb +169 -0
- data/lib/mongo/crypt/auto_encryption_context.rb +44 -0
- data/lib/mongo/crypt/binary.rb +155 -0
- data/lib/mongo/crypt/binding.rb +1162 -0
- data/lib/mongo/crypt/context.rb +135 -0
- data/lib/mongo/crypt/data_key_context.rb +162 -0
- data/lib/mongo/crypt/encryption_io.rb +283 -0
- data/lib/mongo/crypt/explicit_decryption_context.rb +40 -0
- data/lib/mongo/crypt/explicit_encrypter.rb +117 -0
- data/lib/mongo/crypt/explicit_encryption_context.rb +89 -0
- data/lib/mongo/crypt/handle.rb +293 -0
- data/lib/mongo/crypt/hooks.rb +90 -0
- data/lib/mongo/crypt/kms_context.rb +67 -0
- data/lib/mongo/crypt/status.rb +131 -0
- data/lib/mongo/cursor.rb +64 -32
- data/lib/mongo/database.rb +13 -6
- data/lib/mongo/database/view.rb +13 -4
- data/lib/mongo/dbref.rb +9 -2
- data/lib/mongo/error.rb +5 -1
- data/lib/mongo/error/crypt_error.rb +31 -0
- data/lib/mongo/error/{failed_stringprep_validation.rb → failed_string_prep_validation.rb} +0 -0
- data/lib/mongo/error/invalid_cursor_operation.rb +27 -0
- data/lib/mongo/error/kms_error.rb +22 -0
- data/lib/mongo/error/max_bson_size.rb +14 -3
- data/lib/mongo/error/mongocryptd_spawn_error.rb +22 -0
- data/lib/mongo/error/no_server_available.rb +8 -3
- data/lib/mongo/error/operation_failure.rb +1 -0
- data/lib/mongo/grid/file.rb +0 -5
- data/lib/mongo/grid/file/chunk.rb +0 -2
- data/lib/mongo/grid/file/info.rb +2 -1
- data/lib/mongo/grid/fs_bucket.rb +13 -15
- data/lib/mongo/grid/stream/write.rb +3 -9
- data/lib/mongo/index/view.rb +3 -3
- data/lib/mongo/monitoring/event/command_started.rb +6 -1
- data/lib/mongo/operation/collections_info.rb +6 -3
- data/lib/mongo/operation/delete/op_msg.rb +1 -1
- data/lib/mongo/operation/find/op_msg.rb +4 -1
- data/lib/mongo/operation/get_more/op_msg.rb +4 -1
- data/lib/mongo/operation/insert/command.rb +2 -2
- data/lib/mongo/operation/insert/legacy.rb +2 -2
- data/lib/mongo/operation/insert/op_msg.rb +3 -3
- data/lib/mongo/operation/result.rb +36 -27
- data/lib/mongo/operation/shared/executable.rb +10 -8
- data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_command.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_find_command.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +2 -2
- data/lib/mongo/operation/shared/write.rb +17 -10
- data/lib/mongo/operation/update/op_msg.rb +1 -1
- data/lib/mongo/protocol/compressed.rb +6 -5
- data/lib/mongo/protocol/insert.rb +3 -1
- data/lib/mongo/protocol/message.rb +72 -8
- data/lib/mongo/protocol/msg.rb +191 -37
- data/lib/mongo/protocol/query.rb +7 -9
- data/lib/mongo/protocol/serializers.rb +6 -2
- data/lib/mongo/server.rb +10 -4
- data/lib/mongo/server/connection.rb +20 -9
- data/lib/mongo/server/connection_base.rb +81 -12
- data/lib/mongo/server/connection_common.rb +61 -0
- data/lib/mongo/server/connection_pool.rb +37 -1
- data/lib/mongo/server/description.rb +9 -11
- data/lib/mongo/server/monitor.rb +2 -0
- data/lib/mongo/server/monitor/connection.rb +3 -18
- data/lib/mongo/server/pending_connection.rb +2 -1
- data/lib/mongo/session.rb +2 -2
- data/lib/mongo/session/session_pool.rb +8 -3
- data/lib/mongo/socket.rb +29 -16
- data/lib/mongo/socket/ssl.rb +23 -8
- data/lib/mongo/socket/tcp.rb +12 -3
- data/lib/mongo/timeout.rb +49 -0
- data/lib/mongo/uri.rb +30 -1
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/README.md +134 -7
- data/spec/integration/auth_spec.rb +53 -0
- data/spec/integration/{client_options_spec.rb → client_authentication_options_spec.rb} +10 -10
- data/spec/integration/client_construction_spec.rb +76 -1
- data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +351 -0
- data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +301 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +71 -0
- data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +76 -0
- data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +216 -0
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +600 -0
- data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +183 -0
- data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +74 -0
- data/spec/integration/client_side_encryption/client_close_spec.rb +59 -0
- data/spec/integration/client_side_encryption/corpus_spec.rb +228 -0
- data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +132 -0
- data/spec/integration/client_side_encryption/data_key_spec.rb +163 -0
- data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +114 -0
- data/spec/integration/client_side_encryption/external_key_vault_spec.rb +137 -0
- data/spec/integration/client_side_encryption/views_spec.rb +42 -0
- data/spec/integration/client_update_spec.rb +120 -0
- data/spec/integration/command_monitoring_spec.rb +3 -1
- data/spec/integration/command_spec.rb +44 -10
- data/spec/integration/connection_spec.rb +57 -0
- data/spec/integration/reconnect_spec.rb +7 -6
- data/spec/integration/size_limit_spec.rb +94 -0
- data/spec/integration/srv_monitoring_spec.rb +14 -6
- data/spec/lite_spec_helper.rb +31 -22
- data/spec/mongo/auth/cr_spec.rb +8 -0
- data/spec/mongo/auth/ldap_spec.rb +5 -1
- data/spec/mongo/auth/scram/conversation_spec.rb +5 -6
- data/spec/mongo/auth/scram/negotiation_spec.rb +74 -75
- data/spec/mongo/auth/scram_spec.rb +45 -35
- data/spec/mongo/auth/x509_spec.rb +5 -1
- data/spec/mongo/client_construction_spec.rb +206 -3
- data/spec/mongo/client_encryption_spec.rb +408 -0
- data/spec/mongo/cluster/cursor_reaper_spec.rb +12 -8
- data/spec/mongo/cluster/socket_reaper_spec.rb +14 -3
- data/spec/mongo/collection/view/aggregation_spec.rb +0 -2
- data/spec/mongo/collection/view/change_stream_spec.rb +7 -7
- data/spec/mongo/collection/view/map_reduce_spec.rb +3 -3
- data/spec/mongo/collection/view_spec.rb +1 -1
- data/spec/mongo/collection_spec.rb +4 -33
- data/spec/mongo/crypt/auto_decryption_context_spec.rb +90 -0
- data/spec/mongo/crypt/auto_encrypter_spec.rb +182 -0
- data/spec/mongo/crypt/auto_encryption_context_spec.rb +107 -0
- data/spec/mongo/crypt/binary_spec.rb +115 -0
- data/spec/mongo/crypt/binding/binary_spec.rb +56 -0
- data/spec/mongo/crypt/binding/context_spec.rb +257 -0
- data/spec/mongo/crypt/binding/helpers_spec.rb +46 -0
- data/spec/mongo/crypt/binding/mongocrypt_spec.rb +144 -0
- data/spec/mongo/crypt/binding/status_spec.rb +99 -0
- data/spec/mongo/crypt/binding/version_spec.rb +22 -0
- data/spec/mongo/crypt/binding_unloaded_spec.rb +20 -0
- data/spec/mongo/crypt/data_key_context_spec.rb +213 -0
- data/spec/mongo/crypt/encryption_io_spec.rb +136 -0
- data/spec/mongo/crypt/explicit_decryption_context_spec.rb +72 -0
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +170 -0
- data/spec/mongo/crypt/handle_spec.rb +198 -0
- data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +108 -0
- data/spec/mongo/crypt/status_spec.rb +152 -0
- data/spec/mongo/cursor_spec.rb +24 -4
- data/spec/mongo/database_spec.rb +20 -0
- data/spec/mongo/error/crypt_error_spec.rb +26 -0
- data/spec/mongo/error/max_bson_size_spec.rb +35 -0
- data/spec/mongo/error/no_server_available_spec.rb +11 -1
- data/spec/mongo/error/operation_failure_spec.rb +6 -6
- data/spec/mongo/operation/aggregate_spec.rb +1 -1
- data/spec/mongo/operation/collections_info_spec.rb +1 -1
- data/spec/mongo/operation/command_spec.rb +3 -3
- data/spec/mongo/operation/create_index_spec.rb +3 -3
- data/spec/mongo/operation/create_user_spec.rb +3 -3
- data/spec/mongo/operation/delete/bulk_spec.rb +6 -6
- data/spec/mongo/operation/delete/op_msg_spec.rb +1 -6
- data/spec/mongo/operation/delete_spec.rb +7 -7
- data/spec/mongo/operation/drop_index_spec.rb +2 -2
- data/spec/mongo/operation/find/legacy_spec.rb +1 -1
- data/spec/mongo/operation/get_more_spec.rb +1 -1
- data/spec/mongo/operation/indexes_spec.rb +1 -1
- data/spec/mongo/operation/insert/bulk_spec.rb +7 -7
- data/spec/mongo/operation/insert/op_msg_spec.rb +3 -6
- data/spec/mongo/operation/insert_spec.rb +12 -12
- data/spec/mongo/operation/map_reduce_spec.rb +2 -2
- data/spec/mongo/operation/remove_user_spec.rb +3 -3
- data/spec/mongo/operation/update/bulk_spec.rb +6 -6
- data/spec/mongo/operation/update/op_msg_spec.rb +3 -6
- data/spec/mongo/operation/update_spec.rb +7 -7
- data/spec/mongo/operation/update_user_spec.rb +1 -1
- data/spec/mongo/protocol/compressed_spec.rb +2 -3
- data/spec/mongo/protocol/delete_spec.rb +9 -8
- data/spec/mongo/protocol/get_more_spec.rb +9 -8
- data/spec/mongo/protocol/insert_spec.rb +9 -8
- data/spec/mongo/protocol/kill_cursors_spec.rb +6 -5
- data/spec/mongo/protocol/msg_spec.rb +57 -53
- data/spec/mongo/protocol/query_spec.rb +12 -12
- data/spec/mongo/protocol/registry_spec.rb +1 -1
- data/spec/mongo/protocol/reply_spec.rb +1 -1
- data/spec/mongo/protocol/update_spec.rb +10 -9
- data/spec/mongo/server/connection_pool_spec.rb +1 -1
- data/spec/mongo/server/connection_spec.rb +28 -7
- data/spec/mongo/socket_spec.rb +1 -1
- data/spec/mongo/timeout_spec.rb +85 -0
- data/spec/mongo/uri/srv_protocol_spec.rb +2 -2
- data/spec/mongo/uri_spec.rb +52 -5
- data/spec/mongo/write_concern_spec.rb +13 -1
- data/spec/{support → runners}/auth.rb +14 -1
- data/spec/{support → runners}/change_streams.rb +1 -1
- data/spec/{support → runners}/change_streams/operation.rb +0 -0
- data/spec/{support → runners}/cmap.rb +1 -1
- data/spec/{support → runners}/cmap/verifier.rb +0 -0
- data/spec/{support → runners}/command_monitoring.rb +0 -0
- data/spec/runners/connection_string.rb +358 -4
- data/spec/{support → runners}/crud.rb +9 -9
- data/spec/{support → runners}/crud/context.rb +0 -0
- data/spec/{support → runners}/crud/operation.rb +7 -3
- data/spec/{support → runners}/crud/outcome.rb +0 -0
- data/spec/{support → runners}/crud/requirement.rb +1 -1
- data/spec/{support → runners}/crud/spec.rb +12 -1
- data/spec/{support → runners}/crud/test.rb +0 -0
- data/spec/{support → runners}/crud/test_base.rb +0 -0
- data/spec/{support → runners}/crud/verifier.rb +10 -12
- data/spec/{support → runners}/gridfs.rb +0 -0
- data/spec/{support → runners}/sdam_monitoring.rb +0 -0
- data/spec/{support → runners}/server_discovery_and_monitoring.rb +0 -0
- data/spec/{support → runners}/server_selection.rb +0 -0
- data/spec/{support → runners}/server_selection_rtt.rb +0 -0
- data/spec/{support → runners}/transactions.rb +4 -4
- data/spec/{support → runners}/transactions/context.rb +0 -0
- data/spec/{support → runners}/transactions/operation.rb +0 -0
- data/spec/{support → runners}/transactions/spec.rb +0 -0
- data/spec/{support → runners}/transactions/test.rb +37 -5
- data/spec/spec_helper.rb +0 -5
- data/spec/spec_tests/auth_spec.rb +3 -3
- data/spec/spec_tests/client_side_encryption_spec.rb +13 -0
- data/spec/spec_tests/connection_string_spec.rb +1 -1
- data/spec/spec_tests/data/auth/connection-string.yml +13 -0
- data/spec/spec_tests/data/client_side_encryption/aggregate.yml +134 -0
- data/spec/spec_tests/data/client_side_encryption/badQueries.yml +526 -0
- data/spec/spec_tests/data/client_side_encryption/badSchema.yml +73 -0
- data/spec/spec_tests/data/client_side_encryption/basic.yml +116 -0
- data/spec/spec_tests/data/client_side_encryption/bulk.yml +85 -0
- data/spec/spec_tests/data/client_side_encryption/bypassAutoEncryption.yml +100 -0
- data/spec/spec_tests/data/client_side_encryption/bypassedCommand.yml +42 -0
- data/spec/spec_tests/data/client_side_encryption/count.yml +61 -0
- data/spec/spec_tests/data/client_side_encryption/countDocuments.yml +59 -0
- data/spec/spec_tests/data/client_side_encryption/delete.yml +105 -0
- data/spec/spec_tests/data/client_side_encryption/distinct.yml +73 -0
- data/spec/spec_tests/data/client_side_encryption/explain.yml +64 -0
- data/spec/spec_tests/data/client_side_encryption/find.yml +119 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndDelete.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndReplace.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndUpdate.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/getMore.yml +68 -0
- data/spec/spec_tests/data/client_side_encryption/insert.yml +102 -0
- data/spec/spec_tests/data/client_side_encryption/keyAltName.yml +71 -0
- data/spec/spec_tests/data/client_side_encryption/localKMS.yml +54 -0
- data/spec/spec_tests/data/client_side_encryption/localSchema.yml +72 -0
- data/spec/spec_tests/data/client_side_encryption/malformedCiphertext.yml +69 -0
- data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +20 -0
- data/spec/spec_tests/data/client_side_encryption/missingKey.yml +49 -0
- data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +61 -0
- data/spec/spec_tests/data/client_side_encryption/types.yml +527 -0
- data/spec/spec_tests/data/client_side_encryption/unsupportedCommand.yml +25 -0
- data/spec/spec_tests/data/client_side_encryption/updateMany.yml +77 -0
- data/spec/spec_tests/data/client_side_encryption/updateOne.yml +168 -0
- data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +1 -4
- data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +21 -0
- data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +2 -4
- data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +1 -1
- data/spec/spec_tests/data/sdam/rs/primary_mismatched_me_not_removed.yml +73 -0
- data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +1 -2
- data/spec/spec_tests/data/sdam/rs/repeated.yml +101 -0
- data/spec/spec_tests/data/sdam/rs/{primary_address_change.yml → ruby_primary_address_change.yml} +2 -0
- data/spec/spec_tests/data/sdam/rs/{secondary_wrong_set_name_with_primary_second.yml → ruby_secondary_wrong_set_name_with_primary_second.yml} +0 -0
- data/spec/spec_tests/data/sdam/sharded/ruby_discovered_single_mongos.yml +27 -0
- data/spec/spec_tests/data/sdam/sharded/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
- data/spec/spec_tests/data/sdam/sharded/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
- data/spec/spec_tests/data/sdam/single/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
- data/spec/spec_tests/data/sdam/single/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
- data/spec/spec_tests/data/sdam_monitoring/{replica_set_with_primary_change.yml → replica_set_primary_address_change.yml} +27 -5
- data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +26 -74
- data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +20 -16
- data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +73 -0
- data/spec/spec_tests/data/transactions/pin-mongos.yml +2 -3
- data/spec/spec_tests/data/uri_options/auth-options.yml +10 -0
- data/spec/spec_tests/data/uri_options/tls-options.yml +75 -4
- data/spec/spec_tests/read_write_concern_connection_string_spec.rb +1 -1
- data/spec/spec_tests/uri_options_spec.rb +6 -8
- data/spec/stress/connection_pool_timing_spec.rb +6 -3
- data/spec/support/certificates/README.md +4 -0
- data/spec/support/certificates/server-second-level-bundle.pem +77 -77
- data/spec/support/certificates/server-second-level.crt +52 -52
- data/spec/support/certificates/server-second-level.key +25 -25
- data/spec/support/certificates/server-second-level.pem +77 -77
- data/spec/support/client_registry.rb +19 -3
- data/spec/support/cluster_config.rb +9 -1
- data/spec/support/common_shortcuts.rb +12 -0
- data/spec/support/constraints.rb +16 -0
- data/spec/support/crypt.rb +140 -0
- data/spec/support/crypt/corpus/corpus-key-aws.json +33 -0
- data/spec/support/crypt/corpus/corpus-key-local.json +31 -0
- data/spec/support/crypt/corpus/corpus-schema.json +2057 -0
- data/spec/support/crypt/corpus/corpus.json +3657 -0
- data/spec/support/crypt/corpus/corpus_encrypted.json +4152 -0
- data/spec/support/crypt/data_keys/key_document_aws.json +34 -0
- data/spec/support/crypt/data_keys/key_document_local.json +31 -0
- data/spec/support/crypt/external/external-key.json +31 -0
- data/spec/support/crypt/external/external-schema.json +19 -0
- data/spec/support/crypt/limits/limits-doc.json +102 -0
- data/spec/support/crypt/limits/limits-key.json +31 -0
- data/spec/support/crypt/limits/limits-schema.json +1405 -0
- data/spec/support/crypt/schema_maps/schema_map_aws.json +17 -0
- data/spec/support/crypt/schema_maps/schema_map_aws_key_alt_names.json +12 -0
- data/spec/support/crypt/schema_maps/schema_map_local.json +18 -0
- data/spec/support/crypt/schema_maps/schema_map_local_key_alt_names.json +12 -0
- data/spec/support/lite_constraints.rb +17 -1
- data/spec/support/matchers.rb +19 -0
- data/spec/support/shared/protocol.rb +2 -0
- data/spec/support/spec_config.rb +43 -13
- data/spec/support/utils.rb +132 -10
- metadata +277 -81
- metadata.gz.sig +0 -0
- data/spec/integration/grid_fs_bucket_spec.rb +0 -48
- data/spec/integration/zlib_compression_spec.rb +0 -25
- data/spec/spec_tests/data/sdam/sharded/single_mongos.yml +0 -33
- data/spec/support/connection_string.rb +0 -354
@@ -0,0 +1,1162 @@
|
|
1
|
+
# Copyright (C) 2019 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
unless ENV['LIBMONGOCRYPT_PATH']
|
16
|
+
# It seems that MRI maintains autoload configuration for a module until
|
17
|
+
# that module is defined, but JRuby removes autoload configuration as soon
|
18
|
+
# as the referenced file is attempted to be loaded, even if the module
|
19
|
+
# never ends up being defined.
|
20
|
+
if BSON::Environment.jruby?
|
21
|
+
module Mongo
|
22
|
+
module Crypt
|
23
|
+
autoload :Binding, 'mongo/crypt/binding'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
raise LoadError, "Cannot load Mongo::Crypt::Binding because there is no path " +
|
29
|
+
"to libmongocrypt specified in the LIBMONGOCRYPT_PATH environment variable."
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'ffi'
|
33
|
+
|
34
|
+
module Mongo
|
35
|
+
module Crypt
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
def reset_autoload
|
39
|
+
remove_const(:Binding)
|
40
|
+
autoload(:Binding, 'mongo/crypt/binding')
|
41
|
+
end
|
42
|
+
module_function :reset_autoload
|
43
|
+
|
44
|
+
# A Ruby binding for the libmongocrypt C library
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
class Binding
|
48
|
+
extend FFI::Library
|
49
|
+
|
50
|
+
begin
|
51
|
+
ffi_lib ENV['LIBMONGOCRYPT_PATH']
|
52
|
+
rescue LoadError => e
|
53
|
+
Crypt.reset_autoload
|
54
|
+
raise LoadError, "Cannot load Mongo::Crypt::Binding because the path to " +
|
55
|
+
"libmongocrypt specified in the LIBMONGOCRYPT_PATH environment variable " +
|
56
|
+
"is invalid: #{ENV['LIBMONGOCRYPT_PATH']}\n\n#{e.class}: #{e.message}"
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the version string of the libmongocrypt library
|
60
|
+
#
|
61
|
+
# @param [ FFI::Pointer | nil ] len (out param) An optional pointer to a
|
62
|
+
# uint8 that will reference the length of the returned string.
|
63
|
+
#
|
64
|
+
# @return [ String ] A version string for libmongocrypt
|
65
|
+
attach_function :mongocrypt_version, [:pointer], :string
|
66
|
+
|
67
|
+
# Create a new mongocrypt_binary_t object (a non-owning view of a byte
|
68
|
+
# array)
|
69
|
+
#
|
70
|
+
# @return [ FFI::Pointer ] A pointer to the newly-created
|
71
|
+
# mongocrypt_binary_t object
|
72
|
+
attach_function :mongocrypt_binary_new, [], :pointer
|
73
|
+
|
74
|
+
# Create a new mongocrypt_binary_t object that maintains a pointer to
|
75
|
+
# the specified byte array.
|
76
|
+
#
|
77
|
+
# @param [ FFI::Pointer ] data A pointer to an array of bytes; the data
|
78
|
+
# is not copied and must outlive the mongocrypt_binary_t object
|
79
|
+
# @param [ Integer ] len The length of the array argument
|
80
|
+
#
|
81
|
+
# @return [ FFI::Pointer ] A pointer to the newly-created
|
82
|
+
# mongocrypt_binary_t object
|
83
|
+
attach_function(
|
84
|
+
:mongocrypt_binary_new_from_data,
|
85
|
+
[:pointer, :int],
|
86
|
+
:pointer
|
87
|
+
)
|
88
|
+
|
89
|
+
# Get the pointer to the underlying data for the mongocrypt_binary_t
|
90
|
+
#
|
91
|
+
# @param [ FFI::Pointer ] binary A pointer to a mongocrypt_binary_t object
|
92
|
+
#
|
93
|
+
# @return [ FFI::Pointer ] A pointer to the data array
|
94
|
+
attach_function :mongocrypt_binary_data, [:pointer], :pointer
|
95
|
+
|
96
|
+
# Get the length of the underlying data array
|
97
|
+
#
|
98
|
+
# @param [ FFI::Pointer ] binary A pointer to a mongocrypt_binary_t object
|
99
|
+
#
|
100
|
+
# @return [ Integer ] The length of the data array
|
101
|
+
attach_function :mongocrypt_binary_len, [:pointer], :int
|
102
|
+
|
103
|
+
# Destroy the mongocrypt_binary_t object
|
104
|
+
#
|
105
|
+
# @param [ FFI::Pointer ] A pointer to a mongocrypt_binary_t object
|
106
|
+
#
|
107
|
+
# @return [ nil ] Always nil
|
108
|
+
attach_function :mongocrypt_binary_destroy, [:pointer], :void
|
109
|
+
|
110
|
+
# Enum labeling different status types
|
111
|
+
enum :status_type, [
|
112
|
+
:ok, 0,
|
113
|
+
:error_client, 1,
|
114
|
+
:error_kms, 2,
|
115
|
+
]
|
116
|
+
|
117
|
+
# Create a new mongocrypt_status_t object
|
118
|
+
#
|
119
|
+
# @return [ FFI::Pointer ] A pointer to the new mongocrypt_status_ts
|
120
|
+
attach_function :mongocrypt_status_new, [], :pointer
|
121
|
+
|
122
|
+
# Set a message, type, and code on an existing status
|
123
|
+
#
|
124
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
125
|
+
# @param [ Symbol ] type The status type; possible values are defined
|
126
|
+
# by the status_type enum
|
127
|
+
# @param [ Integer ] code The status code
|
128
|
+
# @param [ String ] message The status message
|
129
|
+
# @param [ Integer ] len The length of the message argument (or -1 for a
|
130
|
+
# null-terminated string)
|
131
|
+
#
|
132
|
+
# @return [ nil ] Always nil
|
133
|
+
attach_function(
|
134
|
+
:mongocrypt_status_set,
|
135
|
+
[:pointer, :status_type, :int, :string, :int],
|
136
|
+
:void
|
137
|
+
)
|
138
|
+
|
139
|
+
# Indicates the status type
|
140
|
+
#
|
141
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
142
|
+
#
|
143
|
+
# @return [ Symbol ] The status type (as defined by the status_type enum)
|
144
|
+
attach_function :mongocrypt_status_type, [:pointer], :status_type
|
145
|
+
|
146
|
+
# Return the status error code
|
147
|
+
#
|
148
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
149
|
+
#
|
150
|
+
# @return [ Integer ] The status code
|
151
|
+
attach_function :mongocrypt_status_code, [:pointer], :int
|
152
|
+
|
153
|
+
# Returns the status message
|
154
|
+
#
|
155
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
156
|
+
# @param [ FFI::Pointer | nil ] len (out param) An optional pointer to a
|
157
|
+
# uint32, where the length of the retun string will be written
|
158
|
+
#
|
159
|
+
# @return [ String ] The status message
|
160
|
+
attach_function :mongocrypt_status_message, [:pointer, :pointer], :string
|
161
|
+
|
162
|
+
# Returns whether the status is ok or an error
|
163
|
+
#
|
164
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
165
|
+
#
|
166
|
+
# @return [ Boolean ] Whether the status is ok
|
167
|
+
attach_function :mongocrypt_status_ok, [:pointer], :bool
|
168
|
+
|
169
|
+
# Destroys the reference to the mongocrypt_status_t object
|
170
|
+
#
|
171
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
172
|
+
#
|
173
|
+
# @return [ nil ] Always nil
|
174
|
+
attach_function :mongocrypt_status_destroy, [:pointer], :void
|
175
|
+
|
176
|
+
# Enum labeling the various log levels
|
177
|
+
enum :log_level, [
|
178
|
+
:fatal, 0,
|
179
|
+
:error, 1,
|
180
|
+
:warn, 2,
|
181
|
+
:info, 3,
|
182
|
+
:debug, 4,
|
183
|
+
]
|
184
|
+
|
185
|
+
# A callback to the mongocrypt log function
|
186
|
+
# Set a custom log callback with the mongocrypt_setopt_log_handler method
|
187
|
+
#
|
188
|
+
# @param [ Symbol ] level The log level; possible values defined by the
|
189
|
+
# log_level enum
|
190
|
+
# @param [ String ] message The log message
|
191
|
+
# @param [ Integer ] len The length of the message param, or -1 if the
|
192
|
+
# string is null terminated
|
193
|
+
# @param [ FFI::Pointer | nil ] ctx An optional pointer to a context
|
194
|
+
# object when this callback was set
|
195
|
+
#
|
196
|
+
# @return [ nil ] Always nil.
|
197
|
+
callback :mongocrypt_log_fn_t, [:log_level, :string, :int, :pointer], :void
|
198
|
+
|
199
|
+
# Creates a new mongocrypt_t object
|
200
|
+
#
|
201
|
+
# @return [ FFI::Pointer ] A pointer to a new mongocrypt_t object
|
202
|
+
attach_function :mongocrypt_new, [], :pointer
|
203
|
+
|
204
|
+
# Set the handler on the mongocrypt_t object to be called every time
|
205
|
+
# libmongocrypt logs a message
|
206
|
+
#
|
207
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
208
|
+
# @param [ Method ] log_fn A logging callback method
|
209
|
+
# @param [ FFI::Pointer | nil ] log_ctx An optional pointer to a context
|
210
|
+
# to be passed into the log callback on every invocation.
|
211
|
+
#
|
212
|
+
# @return [ Boolean ] Whether setting the callback was successful
|
213
|
+
attach_function(
|
214
|
+
:mongocrypt_setopt_log_handler,
|
215
|
+
[:pointer, :mongocrypt_log_fn_t, :pointer],
|
216
|
+
:bool
|
217
|
+
)
|
218
|
+
|
219
|
+
# Set the logger callback function on the Mongo::Crypt::Handle object
|
220
|
+
#
|
221
|
+
# @param [ Mongo::Crypt::Handle ] handle
|
222
|
+
# @param [ Method ] log_callback
|
223
|
+
#
|
224
|
+
# @raise [ Mongo::Error::CryptError ] If the callback is not set successfully
|
225
|
+
def self.setopt_log_handler(handle, log_callback)
|
226
|
+
check_status(handle) do
|
227
|
+
mongocrypt_setopt_log_handler(handle, log_callback, nil)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# Configure mongocrypt_t object with AWS KMS provider options
|
232
|
+
#
|
233
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
234
|
+
# @param [ String ] aws_access_key_id The AWS access key id
|
235
|
+
# @param [ Integer ] aws_access_key_id_len The length of the AWS access
|
236
|
+
# key string (or -1 for a null-terminated string)
|
237
|
+
# @param [ String ] aws_secret_access_key The AWS secret access key
|
238
|
+
# @param [ Integer ] aws_secret_access_key_len The length of the AWS
|
239
|
+
# secret access key (or -1 for a null-terminated string)
|
240
|
+
#
|
241
|
+
# @return [ Boolean ] Returns whether the option was set successfully
|
242
|
+
attach_function(
|
243
|
+
:mongocrypt_setopt_kms_provider_aws,
|
244
|
+
[:pointer, :string, :int, :string, :int],
|
245
|
+
:bool
|
246
|
+
)
|
247
|
+
|
248
|
+
# Configure the Handle object with AWS KMS provider options
|
249
|
+
#
|
250
|
+
# @param [ Mongo::Crypt::Handle ] handle
|
251
|
+
# @param [ String ] aws_access_key The AWS access key
|
252
|
+
# @param [ String ] aws_secret_access_key The AWS secret access key
|
253
|
+
#
|
254
|
+
# @raise [ Mongo::Error::CryptError ] If the option is not set successfully
|
255
|
+
def self.setopt_kms_provider_aws(handle,
|
256
|
+
aws_access_key, aws_secret_access_key
|
257
|
+
)
|
258
|
+
check_status(handle) do
|
259
|
+
mongocrypt_setopt_kms_provider_aws(
|
260
|
+
handle.ref,
|
261
|
+
aws_access_key,
|
262
|
+
-1,
|
263
|
+
aws_secret_access_key,
|
264
|
+
-1
|
265
|
+
)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Configure mongocrypt_t object to take local KSM provider options
|
270
|
+
#
|
271
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
272
|
+
# @param [ FFI::Pointer ] key A pointer to a mongocrypt_binary_t object
|
273
|
+
# that references the 96-byte local master key
|
274
|
+
#
|
275
|
+
# @return [ Boolean ] Returns whether the option was set successfully
|
276
|
+
attach_function(
|
277
|
+
:mongocrypt_setopt_kms_provider_local,
|
278
|
+
[:pointer, :pointer],
|
279
|
+
:bool
|
280
|
+
)
|
281
|
+
|
282
|
+
# Set local KMS provider options on the Mongo::Crypt::Handle object
|
283
|
+
#
|
284
|
+
# @param [ Mongo::Crypt::Handle ] handle
|
285
|
+
# @param [ String ] master_key The 96-byte local KMS master key
|
286
|
+
#
|
287
|
+
# @raise [ Mongo::Error::CryptError ] If the option is not set successfully
|
288
|
+
def self.setopt_kms_provider_local(handle, master_key)
|
289
|
+
Binary.wrap_string(master_key) do |master_key_p|
|
290
|
+
check_status(handle) do
|
291
|
+
mongocrypt_setopt_kms_provider_local(handle.ref, master_key_p)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# Sets a local schema map for encryption
|
297
|
+
#
|
298
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
299
|
+
# @param [ FFI::Pointer ] schema_map A pointer to a mongocrypt_binary_t
|
300
|
+
# object that references the schema map as a BSON binary string
|
301
|
+
#
|
302
|
+
# @return [ Boolean ] Returns whether the option was set successfully
|
303
|
+
attach_function :mongocrypt_setopt_schema_map, [:pointer, :pointer], :bool
|
304
|
+
|
305
|
+
# Set schema map on the Mongo::Crypt::Handle object
|
306
|
+
#
|
307
|
+
# @param [ Mongo::Crypt::Handle ] handle
|
308
|
+
# @param [ BSON::Document ] schema_map_doc The schema map as a
|
309
|
+
# BSON::Document object
|
310
|
+
#
|
311
|
+
# @raise [ Mongo::Error::CryptError ] If the schema map is not set successfully
|
312
|
+
def self.setopt_schema_map(handle, schema_map_doc)
|
313
|
+
validate_document(schema_map_doc)
|
314
|
+
data = schema_map_doc.to_bson.to_s
|
315
|
+
Binary.wrap_string(data) do |data_p|
|
316
|
+
check_status(handle) do
|
317
|
+
mongocrypt_setopt_schema_map(handle.ref, data_p)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
# Initialize the mongocrypt_t object
|
323
|
+
#
|
324
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
325
|
+
#
|
326
|
+
# @return [ Boolean ] Returns whether the crypt was initialized successfully
|
327
|
+
attach_function :mongocrypt_init, [:pointer], :bool
|
328
|
+
|
329
|
+
# Initialize the Mongo::Crypt::Handle object
|
330
|
+
#
|
331
|
+
# @param [ Mongo::Crypt::Handle ] handle
|
332
|
+
#
|
333
|
+
# @raise [ Mongo::Error::CryptError ] If initialization fails
|
334
|
+
def self.init(handle)
|
335
|
+
check_status(handle) do
|
336
|
+
mongocrypt_init(handle.ref)
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# Set the status information from the mongocrypt_t object on the
|
341
|
+
# mongocrypt_status_t object
|
342
|
+
#
|
343
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
344
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t object
|
345
|
+
#
|
346
|
+
# @return [ Boolean ] Whether the status was successfully set
|
347
|
+
attach_function :mongocrypt_status, [:pointer, :pointer], :bool
|
348
|
+
|
349
|
+
# Destroy the reference the mongocrypt_t object
|
350
|
+
#
|
351
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
352
|
+
#
|
353
|
+
# @return [ nil ] Always nil
|
354
|
+
attach_function :mongocrypt_destroy, [:pointer], :void
|
355
|
+
|
356
|
+
# Create a new mongocrypt_ctx_t object (a wrapper for the libmongocrypt
|
357
|
+
# state machine)
|
358
|
+
#
|
359
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
360
|
+
#
|
361
|
+
# @return [ FFI::Pointer ] A new mongocrypt_ctx_t object
|
362
|
+
attach_function :mongocrypt_ctx_new, [:pointer], :pointer
|
363
|
+
|
364
|
+
# Set the status information from the mongocrypt_ctx_t object on the
|
365
|
+
# mongocrypt_status_t object
|
366
|
+
#
|
367
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
368
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t object
|
369
|
+
#
|
370
|
+
# @return [ Boolean ] Whether the status was successfully set
|
371
|
+
attach_function :mongocrypt_ctx_status, [:pointer, :pointer], :bool
|
372
|
+
|
373
|
+
# Set the key id used for explicit encryption
|
374
|
+
#
|
375
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
376
|
+
# @param [ FFI::Pointer ] key_id A pointer to a mongocrypt_binary_t object
|
377
|
+
# that references the 16-byte key-id
|
378
|
+
#
|
379
|
+
# @note Do not initialize ctx before calling this method
|
380
|
+
# @return [ Boolean ] Whether the option was successfully set
|
381
|
+
attach_function :mongocrypt_ctx_setopt_key_id, [:pointer, :pointer], :bool
|
382
|
+
|
383
|
+
# Sets the key id option on an explicit encryption context.
|
384
|
+
#
|
385
|
+
# @param [ Mongo::Crypt::Context ] context Explicit encryption context
|
386
|
+
# @param [ String ] key_id The key id
|
387
|
+
#
|
388
|
+
# @raise [ Mongo::Error::CryptError ] If the operation failed
|
389
|
+
def self.ctx_setopt_key_id(context, key_id)
|
390
|
+
Binary.wrap_string(key_id) do |key_id_p|
|
391
|
+
check_ctx_status(context) do
|
392
|
+
mongocrypt_ctx_setopt_key_id(context.ctx_p, key_id_p)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
# When creating a data key, set an alternate name on that key. When
|
398
|
+
# performing explicit encryption, specifying which data key to use for
|
399
|
+
# encryption based on its keyAltName field.
|
400
|
+
#
|
401
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
402
|
+
# @param [ FFI::Pointer ] binary A pointer to a mongocrypt_binary_t
|
403
|
+
# object that references a BSON document in the format
|
404
|
+
# { "keyAltName": <BSON UTF8 value> }
|
405
|
+
#
|
406
|
+
# @return [ Boolean ] Whether the alternative name was successfully set
|
407
|
+
#
|
408
|
+
# @note Do not initialize ctx before calling this method
|
409
|
+
attach_function(
|
410
|
+
:mongocrypt_ctx_setopt_key_alt_name,
|
411
|
+
[:pointer, :pointer],
|
412
|
+
:bool
|
413
|
+
)
|
414
|
+
|
415
|
+
# Set multiple alternate key names on data key creation
|
416
|
+
#
|
417
|
+
# @param [ Mongo::Crypt::Context ] context A DataKeyContext
|
418
|
+
# @param [ Array ] key_alt_names An array of alternate key names as strings
|
419
|
+
#
|
420
|
+
# @raise [ Mongo::Error::CryptError ] If any of the alternate names are
|
421
|
+
# not valid UTF8 strings
|
422
|
+
def self.ctx_setopt_key_alt_names(context, key_alt_names)
|
423
|
+
key_alt_names.each do |key_alt_name|
|
424
|
+
key_alt_name_bson = { :keyAltName => key_alt_name }.to_bson.to_s
|
425
|
+
|
426
|
+
Binary.wrap_string(key_alt_name_bson) do |key_alt_name_p|
|
427
|
+
check_ctx_status(context) do
|
428
|
+
mongocrypt_ctx_setopt_key_alt_name(context.ctx_p, key_alt_name_p)
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
# Set the algorithm used for explicit encryption
|
435
|
+
#
|
436
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
437
|
+
# @param [ String ] algorithm The algorithm name. Valid values are:
|
438
|
+
# - "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
|
439
|
+
# - "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
|
440
|
+
# @param [ Integer ] len The length of the algorithm string
|
441
|
+
#
|
442
|
+
# @note Do not initialize ctx before calling this method
|
443
|
+
# @return [ Boolean ] Whether the option was successfully set
|
444
|
+
attach_function(
|
445
|
+
:mongocrypt_ctx_setopt_algorithm,
|
446
|
+
[:pointer, :string, :int],
|
447
|
+
:bool
|
448
|
+
)
|
449
|
+
|
450
|
+
# Set the algorithm on the context
|
451
|
+
#
|
452
|
+
# @param [ Mongo::Crypt::Context ] context
|
453
|
+
# @param [ String ] name The algorithm name. Valid values are:
|
454
|
+
# - "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
|
455
|
+
# - "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
|
456
|
+
#
|
457
|
+
# @raise [ Mongo::Error::CryptError ] If the operation failed
|
458
|
+
def self.ctx_setopt_algorithm(context, name)
|
459
|
+
check_ctx_status(context) do
|
460
|
+
mongocrypt_ctx_setopt_algorithm(context.ctx_p, name, -1)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
# Configure the ctx to take a master key from AWS
|
465
|
+
#
|
466
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_object
|
467
|
+
# @param [ String ] region The AWS region
|
468
|
+
# @param [ Integer ] region_len The length of the region string (or -1
|
469
|
+
# for a null-terminated string)
|
470
|
+
# @param [ String ] arn The Amazon Resource Name (ARN) of the mater key
|
471
|
+
# @param [ Integer ] arn_len The length of the ARN (or -1 for a
|
472
|
+
# null-terminated string)
|
473
|
+
#
|
474
|
+
# @return [ Boolean ] Returns whether the option was set successfully
|
475
|
+
attach_function(
|
476
|
+
:mongocrypt_ctx_setopt_masterkey_aws,
|
477
|
+
[:pointer, :string, :int, :string, :int],
|
478
|
+
:bool
|
479
|
+
)
|
480
|
+
|
481
|
+
# Configure the Context object to take a master key from AWS
|
482
|
+
#
|
483
|
+
# @param [ Mongo::Crypt::Context ] context
|
484
|
+
# @param [ String ] region The AWS region (e.g. "us-east-2")
|
485
|
+
# @param [ String ] arn The master key Amazon Resource Name
|
486
|
+
#
|
487
|
+
# @raise [ Mongo::Error::CryptError ] If the operation failed
|
488
|
+
def self.ctx_setopt_master_key_aws(context, region, arn)
|
489
|
+
check_ctx_status(context) do
|
490
|
+
mongocrypt_ctx_setopt_masterkey_aws(
|
491
|
+
context.ctx_p,
|
492
|
+
region,
|
493
|
+
-1,
|
494
|
+
arn,
|
495
|
+
-1
|
496
|
+
)
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
# Set a custom endpoint at which to fetch the AWS master key
|
501
|
+
#
|
502
|
+
# @param [ FFI::Pointer ] ctx
|
503
|
+
# @param [ String ] endpoint The custom endpoint
|
504
|
+
# @param [ Integer ] endpoint_len The length of the endpoint string (or
|
505
|
+
# -1 for a null-terminated string)
|
506
|
+
#
|
507
|
+
# @return [ Boolean ] Returns whether the option was set successfully
|
508
|
+
attach_function(
|
509
|
+
:mongocrypt_ctx_setopt_masterkey_aws_endpoint,
|
510
|
+
[:pointer, :string, :int],
|
511
|
+
:bool
|
512
|
+
)
|
513
|
+
|
514
|
+
# Configure the Context object to take a masterk ey from AWS
|
515
|
+
#
|
516
|
+
# @param [ Mongo::Crypt::Context ] context
|
517
|
+
# @param [ String ] endpoint The custom AWS master key endpoint
|
518
|
+
#
|
519
|
+
# @raise [ Mongo::Error::CryptError ] If the operation failed
|
520
|
+
def self.ctx_setopt_master_key_aws_endpoint(context, endpoint)
|
521
|
+
check_ctx_status(context) do
|
522
|
+
mongocrypt_ctx_setopt_masterkey_aws_endpoint(
|
523
|
+
context.ctx_p,
|
524
|
+
endpoint,
|
525
|
+
-1,
|
526
|
+
)
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
# Set the ctx to take a local master key
|
531
|
+
#
|
532
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
533
|
+
#
|
534
|
+
# @note Do not initialize ctx before calling this method
|
535
|
+
# @return [ Boolean ] Whether the option was successfully set
|
536
|
+
attach_function(
|
537
|
+
:mongocrypt_ctx_setopt_masterkey_local,
|
538
|
+
[:pointer],
|
539
|
+
:bool
|
540
|
+
)
|
541
|
+
|
542
|
+
# Tell the Context object to read the master key from local KMS options
|
543
|
+
#
|
544
|
+
# @param [ Mongo::Crypt::Context ] context
|
545
|
+
#
|
546
|
+
# @raise [ Mongo::Error::CryptError ] If the operation failed
|
547
|
+
def self.ctx_setopt_master_key_local(context)
|
548
|
+
check_ctx_status(context) do
|
549
|
+
mongocrypt_ctx_setopt_masterkey_local(context.ctx_p)
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
# Initializes the ctx to create a data key
|
554
|
+
#
|
555
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
556
|
+
#
|
557
|
+
# @note Before calling this method, master key options must be set.
|
558
|
+
# Set AWS master key by calling mongocrypt_ctx_setopt_masterkey_aws
|
559
|
+
# and mongocrypt_ctx_setopt_masterkey_aws_endpoint. Set local master
|
560
|
+
# key by calling mongocrypt_ctx_setopt_masterkey_local.
|
561
|
+
#
|
562
|
+
# @return [ Boolean ] Whether the initialization was successful
|
563
|
+
attach_function :mongocrypt_ctx_datakey_init, [:pointer], :bool
|
564
|
+
|
565
|
+
# Initialize the Context to create a data key
|
566
|
+
#
|
567
|
+
# @param [ Mongo::Crypt::Context ] context
|
568
|
+
#
|
569
|
+
# @raise [ Mongo::Error::CryptError ] If initialization fails
|
570
|
+
def self.ctx_datakey_init(context)
|
571
|
+
check_ctx_status(context) do
|
572
|
+
mongocrypt_ctx_datakey_init(context.ctx_p)
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
# Initializes the ctx for auto-encryption
|
577
|
+
#
|
578
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
579
|
+
# @param [ String ] db The database name
|
580
|
+
# @param [ Integer ] db_len The length of the database name argument (or
|
581
|
+
# -1 for a null-terminated string)
|
582
|
+
# @param [ FFI::Pointer ] cmd A pointer to a mongocrypt_binary_t object
|
583
|
+
# that references the database command as a binary string
|
584
|
+
#
|
585
|
+
# @note This method expects the passed-in BSON to be in the format:
|
586
|
+
# { "v": BSON value to decrypt }
|
587
|
+
#
|
588
|
+
# @return [ Boolean ] Whether the initialization was successful
|
589
|
+
attach_function(
|
590
|
+
:mongocrypt_ctx_encrypt_init,
|
591
|
+
[:pointer, :string, :int, :pointer],
|
592
|
+
:bool
|
593
|
+
)
|
594
|
+
|
595
|
+
# Initialize the Context for auto-encryption
|
596
|
+
#
|
597
|
+
# @param [ Mongo::Crypt::Context ] context
|
598
|
+
# @param [ String ] db_name The name of the database against which the
|
599
|
+
# encrypted command is being performed
|
600
|
+
# @param [ Hash ] command The command to be encrypted
|
601
|
+
#
|
602
|
+
# @raise [ Mongo::Error::CryptError ] If initialization fails
|
603
|
+
def self.ctx_encrypt_init(context, db_name, command)
|
604
|
+
validate_document(command)
|
605
|
+
data = command.to_bson.to_s
|
606
|
+
Binary.wrap_string(data) do |data_p|
|
607
|
+
check_ctx_status(context) do
|
608
|
+
mongocrypt_ctx_encrypt_init(context.ctx_p, db_name, -1, data_p)
|
609
|
+
end
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
# Initializes the ctx for explicit encryption
|
614
|
+
#
|
615
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
616
|
+
# @param [ FFI::Pointer ] msg A pointer to a mongocrypt_binary_t object
|
617
|
+
# that references the message to be encrypted as a binary string
|
618
|
+
#
|
619
|
+
# @note Before calling this method, set a key_id, key_alt_name (optional),
|
620
|
+
# and encryption algorithm using the following methods:
|
621
|
+
# mongocrypt_ctx_setopt_key_id, mongocrypt_ctx_setopt_key_alt_name,
|
622
|
+
# and mongocrypt_ctx_setopt_algorithm
|
623
|
+
#
|
624
|
+
# @return [ Boolean ] Whether the initialization was successful
|
625
|
+
attach_function(
|
626
|
+
:mongocrypt_ctx_explicit_encrypt_init,
|
627
|
+
[:pointer, :pointer],
|
628
|
+
:bool
|
629
|
+
)
|
630
|
+
|
631
|
+
# Initialize the Context for explicit encryption
|
632
|
+
#
|
633
|
+
# @param [ Mongo::Crypt::Context ] context
|
634
|
+
# @param [ Hash ] A BSON document to encrypt
|
635
|
+
#
|
636
|
+
# @raise [ Mongo::Error::CryptError ] If initialization fails
|
637
|
+
def self.ctx_explicit_encrypt_init(context, doc)
|
638
|
+
validate_document(doc)
|
639
|
+
data = doc.to_bson.to_s
|
640
|
+
Binary.wrap_string(data) do |data_p|
|
641
|
+
check_ctx_status(context) do
|
642
|
+
mongocrypt_ctx_explicit_encrypt_init(context.ctx_p, data_p)
|
643
|
+
end
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
# Initializes the ctx for auto-decryption
|
648
|
+
#
|
649
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
650
|
+
# @param [ FFI::Pointer ] doc A pointer to a mongocrypt_binary_t object
|
651
|
+
# that references the document to be decrypted as a BSON binary string
|
652
|
+
#
|
653
|
+
# @return [ Boolean ] Whether the initialization was successful
|
654
|
+
attach_function :mongocrypt_ctx_decrypt_init, [:pointer, :pointer], :bool
|
655
|
+
|
656
|
+
# Initialize the Context for auto-decryption
|
657
|
+
#
|
658
|
+
# @param [ Mongo::Crypt::Context ] context
|
659
|
+
# @param [ BSON::Document ] A BSON document to decrypt
|
660
|
+
#
|
661
|
+
# @raise [ Mongo::Error::CryptError ] If initialization fails
|
662
|
+
def self.ctx_decrypt_init(context, command)
|
663
|
+
validate_document(command)
|
664
|
+
data = command.to_bson.to_s
|
665
|
+
Binary.wrap_string(data) do |data_p|
|
666
|
+
check_ctx_status(context) do
|
667
|
+
mongocrypt_ctx_decrypt_init(context.ctx_p, data_p)
|
668
|
+
end
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
# Initializes the ctx for explicit decryption
|
673
|
+
#
|
674
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
675
|
+
# @param [ FFI::Pointer ] msg A pointer to a mongocrypt_binary_t object
|
676
|
+
# that references the message to be decrypted as a BSON binary string
|
677
|
+
#
|
678
|
+
# @return [ Boolean ] Whether the initialization was successful
|
679
|
+
attach_function(
|
680
|
+
:mongocrypt_ctx_explicit_decrypt_init,
|
681
|
+
[:pointer, :pointer],
|
682
|
+
:bool
|
683
|
+
)
|
684
|
+
|
685
|
+
# Initialize the Context for explicit decryption
|
686
|
+
#
|
687
|
+
# @param [ Mongo::Crypt::Context ] context
|
688
|
+
# @param [ Hash ] A BSON document to decrypt
|
689
|
+
#
|
690
|
+
# @raise [ Mongo::Error::CryptError ] If initialization fails
|
691
|
+
def self.ctx_explicit_decrypt_init(context, doc)
|
692
|
+
validate_document(doc)
|
693
|
+
data = doc.to_bson.to_s
|
694
|
+
Binary.wrap_string(data) do |data_p|
|
695
|
+
check_ctx_status(context) do
|
696
|
+
mongocrypt_ctx_explicit_decrypt_init(context.ctx_p, data_p)
|
697
|
+
end
|
698
|
+
end
|
699
|
+
end
|
700
|
+
|
701
|
+
# An enum labeling different libmognocrypt state machine states
|
702
|
+
enum :mongocrypt_ctx_state, [
|
703
|
+
:error, 0,
|
704
|
+
:need_mongo_collinfo, 1,
|
705
|
+
:need_mongo_markings, 2,
|
706
|
+
:need_mongo_keys, 3,
|
707
|
+
:need_kms, 4,
|
708
|
+
:ready, 5,
|
709
|
+
:done, 6,
|
710
|
+
]
|
711
|
+
|
712
|
+
# Get the current state of the ctx
|
713
|
+
#
|
714
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
715
|
+
#
|
716
|
+
# @return [ Symbol ] The current state, will be one of the values defined
|
717
|
+
# by the mongocrypt_ctx_state enum
|
718
|
+
attach_function :mongocrypt_ctx_state, [:pointer], :mongocrypt_ctx_state
|
719
|
+
|
720
|
+
# Get a BSON operation for the driver to run against the MongoDB
|
721
|
+
# collection, the key vault database, or mongocryptd.
|
722
|
+
#
|
723
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
724
|
+
# @param [ FFI::Pointer ] op_bson (out param) A pointer to a
|
725
|
+
# mongocrypt_binary_t object that will have a reference to the
|
726
|
+
# BSON operation written to it by libmongocrypt
|
727
|
+
#
|
728
|
+
# @return [ Boolean ] A boolean indicating the success of the operation
|
729
|
+
attach_function :mongocrypt_ctx_mongo_op, [:pointer, :pointer], :bool
|
730
|
+
|
731
|
+
# Returns a BSON::Document representing an operation that the
|
732
|
+
# driver must perform on behalf of libmongocrypt to get the
|
733
|
+
# information it needs in order to continue with
|
734
|
+
# encryption/decryption (for example, a filter for a key vault query).
|
735
|
+
#
|
736
|
+
# @param [ Mongo::Crypt::Context ] context
|
737
|
+
#
|
738
|
+
# @raise [ Mongo::Crypt ] If there is an error getting the operation
|
739
|
+
# @return [ BSON::Document ] The operation that the driver must perform
|
740
|
+
def self.ctx_mongo_op(context)
|
741
|
+
binary = Binary.new
|
742
|
+
|
743
|
+
check_ctx_status(context) do
|
744
|
+
mongocrypt_ctx_mongo_op(context.ctx_p, binary.ref)
|
745
|
+
end
|
746
|
+
|
747
|
+
# TODO since the binary references a C pointer, and ByteBuffer is
|
748
|
+
# written in C in MRI, we could omit a copy of the data by making
|
749
|
+
# ByteBuffer reference the string that is owned by libmongocrypt.
|
750
|
+
BSON::Document.from_bson(BSON::ByteBuffer.new(binary.to_s), mode: :bson)
|
751
|
+
end
|
752
|
+
|
753
|
+
# Feed a BSON reply to libmongocrypt
|
754
|
+
#
|
755
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
756
|
+
# @param [ FFI::Pointer ] reply A mongocrypt_binary_t object that
|
757
|
+
# references the BSON reply to feed to libmongocrypt
|
758
|
+
#
|
759
|
+
# @return [ Boolean ] A boolean indicating the success of the operation
|
760
|
+
attach_function :mongocrypt_ctx_mongo_feed, [:pointer, :pointer], :bool
|
761
|
+
|
762
|
+
# Feed a response from the driver back to libmongocrypt
|
763
|
+
#
|
764
|
+
# @param [ Mongo::Crypt::Context ] context
|
765
|
+
# @param [ BSON::Document ] doc The document representing the response
|
766
|
+
#
|
767
|
+
# @raise [ Mongo::Error::CryptError ] If the response is not fed successfully
|
768
|
+
def self.ctx_mongo_feed(context, doc)
|
769
|
+
validate_document(doc)
|
770
|
+
data = doc.to_bson.to_s
|
771
|
+
Binary.wrap_string(data) do |data_p|
|
772
|
+
check_ctx_status(context) do
|
773
|
+
mongocrypt_ctx_mongo_feed(context.ctx_p, data_p)
|
774
|
+
end
|
775
|
+
end
|
776
|
+
end
|
777
|
+
|
778
|
+
# Indicate to libmongocrypt that the driver is done feeding replies
|
779
|
+
#
|
780
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
781
|
+
#
|
782
|
+
# @return [ Boolean ] A boolean indicating the success of the operation
|
783
|
+
attach_function :mongocrypt_ctx_mongo_done, [:pointer], :bool
|
784
|
+
|
785
|
+
# Return a pointer to a mongocrypt_kms_ctx_t object or NULL.
|
786
|
+
#
|
787
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
788
|
+
#
|
789
|
+
# @return [ FFI::Pointer ] A pointer to a mongocrypt_kms_ctx_t object
|
790
|
+
attach_function :mongocrypt_ctx_next_kms_ctx, [:pointer], :pointer
|
791
|
+
|
792
|
+
# Return a new KmsContext object needed by a Context object.
|
793
|
+
#
|
794
|
+
# @param [ Mongo::Crypt::Context ] context
|
795
|
+
#
|
796
|
+
# @return [ Mongo::Crypt::KmsContext | nil ] The KmsContext needed to
|
797
|
+
# fetch an AWS master key or nil, if no KmsContext is needed
|
798
|
+
def self.ctx_next_kms_ctx(context)
|
799
|
+
kms_ctx_p = mongocrypt_ctx_next_kms_ctx(context.ctx_p)
|
800
|
+
|
801
|
+
if kms_ctx_p.null?
|
802
|
+
nil
|
803
|
+
else
|
804
|
+
KmsContext.new(kms_ctx_p)
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
# Get the message needed to fetch the AWS KMS master key.
|
809
|
+
#
|
810
|
+
# @param [ FFI::Pointer ] kms Pointer to the mongocrypt_kms_ctx_t object
|
811
|
+
# @param [ FFI::Pointer ] msg (outparam) Pointer to a mongocrypt_binary_t
|
812
|
+
# object that will have the location of the message written to it by
|
813
|
+
# libmongocrypt
|
814
|
+
#
|
815
|
+
# @return [ Boolean ] Whether the operation is successful
|
816
|
+
attach_function :mongocrypt_kms_ctx_message, [:pointer, :pointer], :bool
|
817
|
+
|
818
|
+
# Get the HTTP message needed to fetch the AWS KMS master key from a
|
819
|
+
# KmsContext object.
|
820
|
+
#
|
821
|
+
# @param [ Mongo::Crypt::KmsContext ] kms_context
|
822
|
+
#
|
823
|
+
# @raise [ Mongo::Error::CryptError ] If the response is not fed successfully
|
824
|
+
#
|
825
|
+
# @return [ String ] The HTTP message
|
826
|
+
def self.kms_ctx_message(kms_context)
|
827
|
+
binary = Binary.new
|
828
|
+
|
829
|
+
check_kms_ctx_status(kms_context) do
|
830
|
+
mongocrypt_kms_ctx_message(kms_context.kms_ctx_p, binary.ref)
|
831
|
+
end
|
832
|
+
|
833
|
+
return binary.to_s
|
834
|
+
end
|
835
|
+
|
836
|
+
# Get the hostname with which to connect over TLS to get information about
|
837
|
+
# the AWS master key.
|
838
|
+
#
|
839
|
+
# @param [ FFI::Pointer ] kms A pointer to a mongocrypt_kms_ctx_t object
|
840
|
+
# @param [ FFI::Pointer ] endpoint (out param) A pointer to which the
|
841
|
+
# endpoint string will be written by libmongocrypt
|
842
|
+
#
|
843
|
+
# @return [ Boolean ] Whether the operation was successful
|
844
|
+
attach_function :mongocrypt_kms_ctx_endpoint, [:pointer, :pointer], :bool
|
845
|
+
|
846
|
+
# Get the hostname with which to connect over TLS to get information
|
847
|
+
# about the AWS master key.
|
848
|
+
#
|
849
|
+
# @param [ Mongo::Crypt::KmsContext ] kms_context
|
850
|
+
#
|
851
|
+
# @raise [ Mongo::Error::CryptError ] If the response is not fed successfully
|
852
|
+
#
|
853
|
+
# @return [ String | nil ] The hostname, or nil if none exists
|
854
|
+
def self.kms_ctx_endpoint(kms_context)
|
855
|
+
ptr = FFI::MemoryPointer.new(:pointer, 1)
|
856
|
+
|
857
|
+
check_kms_ctx_status(kms_context) do
|
858
|
+
mongocrypt_kms_ctx_endpoint(kms_context.kms_ctx_p, ptr)
|
859
|
+
end
|
860
|
+
|
861
|
+
str_ptr = ptr.read_pointer
|
862
|
+
str_ptr.null? ? nil : str_ptr.read_string.force_encoding('UTF-8')
|
863
|
+
end
|
864
|
+
|
865
|
+
# Get the number of bytes needed by the KMS context.
|
866
|
+
#
|
867
|
+
# @param [ FFI::Pointer ] kms The mongocrypt_kms_ctx_t object
|
868
|
+
#
|
869
|
+
# @return [ Integer ] The number of bytes needed
|
870
|
+
attach_function :mongocrypt_kms_ctx_bytes_needed, [:pointer], :int
|
871
|
+
|
872
|
+
# Get the number of bytes needed by the KmsContext.
|
873
|
+
#
|
874
|
+
# @param [ Mongo::Crypt::KmsContext ] kms_context
|
875
|
+
#
|
876
|
+
# @return [ Integer ] The number of bytes needed
|
877
|
+
def self.kms_ctx_bytes_needed(kms_context)
|
878
|
+
mongocrypt_kms_ctx_bytes_needed(kms_context.kms_ctx_p)
|
879
|
+
end
|
880
|
+
|
881
|
+
# Feed replies from the KMS back to libmongocrypt.
|
882
|
+
#
|
883
|
+
# @param [ FFI::Pointer ] kms A pointer to the mongocrypt_kms_ctx_t object
|
884
|
+
# @param [ FFI::Pointer ] bytes A pointer to a mongocrypt_binary_t
|
885
|
+
# object that references the response from the KMS
|
886
|
+
#
|
887
|
+
# @return [ Boolean ] Whether the operation was successful
|
888
|
+
attach_function :mongocrypt_kms_ctx_feed, [:pointer, :pointer], :bool
|
889
|
+
|
890
|
+
# Feed replies from the KMS back to libmongocrypt.
|
891
|
+
#
|
892
|
+
# @param [ Mongo::Crypt::KmsContext ] kms_context
|
893
|
+
# @oaram [ String ] data The data to feed to libmongocrypt
|
894
|
+
#
|
895
|
+
# @raise [ Mongo::Error::CryptError ] If the response is not fed successfully
|
896
|
+
def self.kms_ctx_feed(kms_context, bytes)
|
897
|
+
check_kms_ctx_status(kms_context) do
|
898
|
+
Binary.wrap_string(bytes) do |bytes_p|
|
899
|
+
mongocrypt_kms_ctx_feed(kms_context.kms_ctx_p, bytes_p)
|
900
|
+
end
|
901
|
+
end
|
902
|
+
end
|
903
|
+
|
904
|
+
# Write status information about the mongocrypt_kms_ctx_t object
|
905
|
+
# to the mongocrypt_status_t object.
|
906
|
+
#
|
907
|
+
# @param [ FFI::Pointer ] kms A pointer to the mongocrypt_kms_ctx_t object
|
908
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t object
|
909
|
+
#
|
910
|
+
# @return [ Boolean ] Whether the operation was successful
|
911
|
+
attach_function :mongocrypt_kms_ctx_status, [:pointer, :pointer], :bool
|
912
|
+
|
913
|
+
# If the provided block returns false, raise a CryptError with the
|
914
|
+
# status information from the provided KmsContext object.
|
915
|
+
#
|
916
|
+
# @param [ Mongo::Crypt::KmsContext ] kms_context
|
917
|
+
#
|
918
|
+
# @raise [ Mongo::Error::CryptError ] If the provided block returns false
|
919
|
+
def self.check_kms_ctx_status(kms_context)
|
920
|
+
unless yield
|
921
|
+
status = Status.new
|
922
|
+
|
923
|
+
mongocrypt_kms_ctx_status(kms_context.kms_ctx_p, status.ref)
|
924
|
+
status.raise_crypt_error
|
925
|
+
end
|
926
|
+
end
|
927
|
+
|
928
|
+
# Indicate to libmongocrypt that it will receive no more replies from
|
929
|
+
# mongocrypt_kms_ctx_t objects.
|
930
|
+
#
|
931
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
932
|
+
#
|
933
|
+
# @return [ Boolean ] Whether the operation was successful
|
934
|
+
attach_function :mongocrypt_ctx_kms_done, [:pointer], :bool
|
935
|
+
|
936
|
+
# Indicate to libmongocrypt that it will receive no more KMS replies.
|
937
|
+
#
|
938
|
+
# @param [ Mongo::Crypt::Context ] context
|
939
|
+
#
|
940
|
+
# @raise [ Mongo::Error::CryptError ] If the operation is unsuccessful
|
941
|
+
def self.ctx_kms_done(context)
|
942
|
+
check_ctx_status(context) do
|
943
|
+
mongocrypt_ctx_kms_done(context.ctx_p)
|
944
|
+
end
|
945
|
+
end
|
946
|
+
|
947
|
+
# Perform the final encryption or decryption and return a BSON document
|
948
|
+
#
|
949
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
950
|
+
# @param [ FFI::Pointer ] op_bson (out param) A pointer to a
|
951
|
+
# mongocrypt_binary_t object that will have a reference to the
|
952
|
+
# final encrypted BSON document
|
953
|
+
#
|
954
|
+
# @return [ Boolean ] A boolean indicating the success of the operation
|
955
|
+
attach_function :mongocrypt_ctx_finalize, [:pointer, :pointer], :void
|
956
|
+
|
957
|
+
# Finalize the state machine represented by the Context
|
958
|
+
#
|
959
|
+
# @param [ Mongo::Crypt::Context ] context
|
960
|
+
#
|
961
|
+
# @raise [ Mongo::Error::CryptError ] If the state machine is not successfully
|
962
|
+
# finalized
|
963
|
+
def self.ctx_finalize(context)
|
964
|
+
binary = Binary.new
|
965
|
+
|
966
|
+
check_ctx_status(context) do
|
967
|
+
mongocrypt_ctx_finalize(context.ctx_p, binary.ref)
|
968
|
+
end
|
969
|
+
|
970
|
+
# TODO since the binary references a C pointer, and ByteBuffer is
|
971
|
+
# written in C in MRI, we could omit a copy of the data by making
|
972
|
+
# ByteBuffer reference the string that is owned by libmongocrypt.
|
973
|
+
BSON::Document.from_bson(BSON::ByteBuffer.new(binary.to_s), mode: :bson)
|
974
|
+
end
|
975
|
+
|
976
|
+
# Destroy the reference to the mongocrypt_ctx_t object
|
977
|
+
#
|
978
|
+
# @param [ FFI::Pointer ] ctx A pointer to a mongocrypt_ctx_t object
|
979
|
+
#
|
980
|
+
# @return [ nil ] Always nil
|
981
|
+
attach_function :mongocrypt_ctx_destroy, [:pointer], :void
|
982
|
+
|
983
|
+
# A callback to a function that performs AES encryption or decryption
|
984
|
+
#
|
985
|
+
# @param [ FFI::Pointer | nil] ctx An optional pointer to a context object
|
986
|
+
# that may have been set when hooks were enabled.
|
987
|
+
# @param [ FFI::Pointer ] key A pointer to a mongocrypt_binary_t object
|
988
|
+
# that references the 32-byte AES encryption key
|
989
|
+
# @param [ FFI::Pointer ] iv A pointer to a mongocrypt_binary_t object
|
990
|
+
# that references the 16-byte AES IV
|
991
|
+
# @param [ FFI::Pointer ] in A pointer to a mongocrypt_binary_t object
|
992
|
+
# that references the value to be encrypted/decrypted
|
993
|
+
# @param [ FFI::Pointer ] out (out param) A pointer to a
|
994
|
+
# mongocrypt_binary_t object will have a reference to the encrypted/
|
995
|
+
# decrypted value written to it by libmongocrypt
|
996
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
997
|
+
# object to which an error message will be written if encryption fails
|
998
|
+
#
|
999
|
+
# @return [ Bool ] Whether encryption/decryption was successful
|
1000
|
+
callback(
|
1001
|
+
:mongocrypt_crypto_fn,
|
1002
|
+
[:pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer],
|
1003
|
+
:bool
|
1004
|
+
)
|
1005
|
+
|
1006
|
+
# A callback to a function that performs HMAC SHA-512 or SHA-256
|
1007
|
+
#
|
1008
|
+
# @param [ FFI::Pointer | nil ] ctx An optional pointer to a context object
|
1009
|
+
# that may have been set when hooks were enabled.
|
1010
|
+
# @param [ FFI::Pointer ] key A pointer to a mongocrypt_binary_t object
|
1011
|
+
# that references the 32-byte HMAC SHA encryption key
|
1012
|
+
# @param [ FFI::Pointer ] in A pointer to a mongocrypt_binary_t object
|
1013
|
+
# that references the input value
|
1014
|
+
# @param [ FFI::Pointer ] out (out param) A pointer to a
|
1015
|
+
# mongocrypt_binary_t object will have a reference to the output value
|
1016
|
+
# written to it by libmongocrypt
|
1017
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
1018
|
+
# object to which an error message will be written if encryption fails
|
1019
|
+
#
|
1020
|
+
# @return [ Bool ] Whether HMAC-SHA was successful
|
1021
|
+
callback(
|
1022
|
+
:mongocrypt_hmac_fn,
|
1023
|
+
[:pointer, :pointer, :pointer, :pointer, :pointer],
|
1024
|
+
:bool
|
1025
|
+
)
|
1026
|
+
|
1027
|
+
# A callback to a SHA-256 hash function
|
1028
|
+
#
|
1029
|
+
# @param [ FFI::Pointer | nil ] ctx An optional pointer to a context object
|
1030
|
+
# that may have been set when hooks were enabled.
|
1031
|
+
# @param [ FFI::Pointer ] in A pointer to a mongocrypt_binary_t object
|
1032
|
+
# that references the value to be hashed
|
1033
|
+
# @param [ FFI::Pointer ] out (out param) A pointer to a
|
1034
|
+
# mongocrypt_binary_t object will have a reference to the output value
|
1035
|
+
# written to it by libmongocrypt
|
1036
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
1037
|
+
# object to which an error message will be written if encryption fails
|
1038
|
+
#
|
1039
|
+
# @return [ Bool ] Whether hashing was successful
|
1040
|
+
callback :mongocrypt_hash_fn, [:pointer, :pointer, :pointer, :pointer], :bool
|
1041
|
+
|
1042
|
+
# A callback to a crypto secure random function
|
1043
|
+
#
|
1044
|
+
# @param [ FFI::Pointer | nil ] ctx An optional pointer to a context object
|
1045
|
+
# that may have been set when hooks were enabled.
|
1046
|
+
# @param [ FFI::Pointer ] out (out param) A pointer to a
|
1047
|
+
# mongocrypt_binary_t object will have a reference to the output value
|
1048
|
+
# written to it by libmongocrypt
|
1049
|
+
# @param [ Integer ] count The number of random bytes to return
|
1050
|
+
# @param [ FFI::Pointer ] status A pointer to a mongocrypt_status_t
|
1051
|
+
# object to which an error message will be written if encryption fails
|
1052
|
+
#
|
1053
|
+
# @return [ Bool ] Whether hashing was successful
|
1054
|
+
callback :mongocrypt_random_fn, [:pointer, :pointer, :int, :pointer], :bool
|
1055
|
+
|
1056
|
+
# Set crypto hooks on the provided mongocrypt object
|
1057
|
+
#
|
1058
|
+
# @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object
|
1059
|
+
# @param [ Proc ] An AES encryption method
|
1060
|
+
# @param [ Proc ] An AES decryption method
|
1061
|
+
# @param [ Proc ] A random method
|
1062
|
+
# @param [ Proc ] A HMAC SHA-512 method
|
1063
|
+
# @param [ Proc ] A HMAC SHA-256 method
|
1064
|
+
# @param [ Proc ] A SHA-256 hash method
|
1065
|
+
# @param [ FFI::Pointer | nil ] ctx An optional pointer to a context object
|
1066
|
+
# that may have been set when hooks were enabled.
|
1067
|
+
#
|
1068
|
+
# @return [ Boolean ] Whether setting this option succeeded
|
1069
|
+
attach_function(
|
1070
|
+
:mongocrypt_setopt_crypto_hooks,
|
1071
|
+
[
|
1072
|
+
:pointer,
|
1073
|
+
:mongocrypt_crypto_fn,
|
1074
|
+
:mongocrypt_crypto_fn,
|
1075
|
+
:mongocrypt_random_fn,
|
1076
|
+
:mongocrypt_hmac_fn,
|
1077
|
+
:mongocrypt_hmac_fn,
|
1078
|
+
:mongocrypt_hash_fn,
|
1079
|
+
:pointer
|
1080
|
+
],
|
1081
|
+
:bool
|
1082
|
+
)
|
1083
|
+
|
1084
|
+
# Set crypto callbacks on the Handle
|
1085
|
+
#
|
1086
|
+
# @param [ Mongo::Crypt::Handle ] handle
|
1087
|
+
# @param [ Method ] aes_encrypt_cb An AES encryption method
|
1088
|
+
# @param [ Method ] aes_decrypt_cb A AES decryption method
|
1089
|
+
# @param [ Method ] random_cb A method that returns a string of random bytes
|
1090
|
+
# @param [ Method ] hmac_sha_512_cb A HMAC SHA-512 method
|
1091
|
+
# @param [ Method ] hmac_sha_256_cb A HMAC SHA-256 method
|
1092
|
+
# @param [ Method ] hmac_hash_cb A SHA-256 hash method
|
1093
|
+
#
|
1094
|
+
# @raise [ Mongo::Error::CryptError ] If the callbacks aren't set successfully
|
1095
|
+
def self.setopt_crypto_hooks(handle,
|
1096
|
+
aes_encrypt_cb, aes_decrypt_cb, random_cb,
|
1097
|
+
hmac_sha_512_cb, hmac_sha_256_cb, hmac_hash_cb
|
1098
|
+
)
|
1099
|
+
check_status(handle) do
|
1100
|
+
mongocrypt_setopt_crypto_hooks(handle.ref,
|
1101
|
+
aes_encrypt_cb, aes_decrypt_cb, random_cb,
|
1102
|
+
hmac_sha_512_cb, hmac_sha_256_cb, hmac_hash_cb, nil
|
1103
|
+
)
|
1104
|
+
end
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
# Raise a Mongo::Error::CryptError based on the status of the underlying
|
1108
|
+
# mongocrypt_t object.
|
1109
|
+
#
|
1110
|
+
# @return [ nil ] Always nil.
|
1111
|
+
def self.check_status(handle)
|
1112
|
+
unless yield
|
1113
|
+
status = Status.new
|
1114
|
+
|
1115
|
+
mongocrypt_status(handle.ref, status.ref)
|
1116
|
+
status.raise_crypt_error
|
1117
|
+
end
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
# Raise a Mongo::Error::CryptError based on the status of the underlying
|
1121
|
+
# mongocrypt_ctx_t object.
|
1122
|
+
#
|
1123
|
+
# @return [ nil ] Always nil.
|
1124
|
+
def self.check_ctx_status(context)
|
1125
|
+
if block_given?
|
1126
|
+
do_raise = !yield
|
1127
|
+
else
|
1128
|
+
do_raise = true
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
if do_raise
|
1132
|
+
status = Status.new
|
1133
|
+
|
1134
|
+
mongocrypt_ctx_status(context.ctx_p, status.ref)
|
1135
|
+
status.raise_crypt_error
|
1136
|
+
end
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
# Checks that the specified data is a Hash before serializing
|
1140
|
+
# it to BSON to prevent errors from libmongocrypt
|
1141
|
+
#
|
1142
|
+
# @note All BSON::Document instances are also Hash instances
|
1143
|
+
#
|
1144
|
+
# @param [ Object ] data The data to be passed to libmongocrypt
|
1145
|
+
#
|
1146
|
+
# @raise [ Mongo::Error::CryptError ] If the data is not a Hash
|
1147
|
+
def self.validate_document(data)
|
1148
|
+
return if data.is_a?(Hash)
|
1149
|
+
|
1150
|
+
if data.nil?
|
1151
|
+
message = "Attempted to pass nil data to libmongocrypt. " +
|
1152
|
+
"Data must be a Hash"
|
1153
|
+
else
|
1154
|
+
message = "Attempted to pass invalid data to libmongocrypt: #{data} " +
|
1155
|
+
"Data must be a Hash"
|
1156
|
+
end
|
1157
|
+
|
1158
|
+
raise Error::CryptError.new(message)
|
1159
|
+
end
|
1160
|
+
end
|
1161
|
+
end
|
1162
|
+
end
|