class Mongo::Crypt::Binding
A Ruby binding for the libmongocrypt C library
@api private
Public Class Methods
Raise a Mongo::Error::CryptError
based on the status of the underlying mongocrypt_ctx_t object.
@return [ nil ] Always nil.
# File lib/mongo/crypt/binding.rb, line 1191 def self.check_ctx_status(context) if block_given? do_raise = !yield else do_raise = true end if do_raise status = Status.new mongocrypt_ctx_status(context.ctx_p, status.ref) status.raise_crypt_error end end
If the provided block returns false, raise a CryptError with the status information from the provided KmsContext
object.
@param [ Mongo::Crypt::KmsContext
] kms_context
@raise [ Mongo::Error::CryptError
] If the provided block returns false
# File lib/mongo/crypt/binding.rb, line 966 def self.check_kms_ctx_status(kms_context) unless yield status = Status.new mongocrypt_kms_ctx_status(kms_context.kms_ctx_p, status.ref) status.raise_crypt_error end end
Raise a Mongo::Error::CryptError
based on the status of the underlying mongocrypt_t object.
@return [ nil ] Always nil.
# File lib/mongo/crypt/binding.rb, line 1178 def self.check_status(handle) unless yield status = Status.new mongocrypt_status(handle.ref, status.ref) status.raise_crypt_error end end
Initialize the Context
to create a data key
@param [ Mongo::Crypt::Context
] context
@raise [ Mongo::Error::CryptError
] If initialization fails
# File lib/mongo/crypt/binding.rb, line 605 def self.ctx_datakey_init(context) check_ctx_status(context) do mongocrypt_ctx_datakey_init(context.ctx_p) end end
Initialize the Context
for auto-decryption
@param [ Mongo::Crypt::Context
] context @param [ BSON::Document ] command A BSON document to decrypt
@raise [ Mongo::Error::CryptError
] If initialization fails
# File lib/mongo/crypt/binding.rb, line 698 def self.ctx_decrypt_init(context, command) validate_document(command) data = command.to_bson.to_s Binary.wrap_string(data) do |data_p| check_ctx_status(context) do mongocrypt_ctx_decrypt_init(context.ctx_p, data_p) end end end
Initialize the Context
for auto-encryption
@param [ Mongo::Crypt::Context
] context @param [ String ] db_name The name of the database against which the
encrypted command is being performed
@param [ Hash ] command The command to be encrypted
@raise [ Mongo::Error::CryptError
] If initialization fails
# File lib/mongo/crypt/binding.rb, line 638 def self.ctx_encrypt_init(context, db_name, command) validate_document(command) data = command.to_bson.to_s Binary.wrap_string(data) do |data_p| check_ctx_status(context) do mongocrypt_ctx_encrypt_init(context.ctx_p, db_name, -1, data_p) end end end
Initialize the Context
for explicit decryption
@param [ Mongo::Crypt::Context
] context @param [ Hash ] doc A BSON document to decrypt
@raise [ Mongo::Error::CryptError
] If initialization fails
# File lib/mongo/crypt/binding.rb, line 728 def self.ctx_explicit_decrypt_init(context, doc) validate_document(doc) data = doc.to_bson.to_s Binary.wrap_string(data) do |data_p| check_ctx_status(context) do mongocrypt_ctx_explicit_decrypt_init(context.ctx_p, data_p) end end end
Initialize the Context
for explicit encryption
@param [ Mongo::Crypt::Context
] context @param [ Hash ] doc A BSON document to encrypt
@raise [ Mongo::Error::CryptError
] If initialization fails
# File lib/mongo/crypt/binding.rb, line 672 def self.ctx_explicit_encrypt_init(context, doc) validate_document(doc) data = doc.to_bson.to_s Binary.wrap_string(data) do |data_p| check_ctx_status(context) do mongocrypt_ctx_explicit_encrypt_init(context.ctx_p, data_p) end end end
Finalize the state machine represented by the Context
@param [ Mongo::Crypt::Context
] context
@raise [ Mongo::Error::CryptError
] If the state machine is not successfully
finalized
# File lib/mongo/crypt/binding.rb, line 1012 def self.ctx_finalize(context) binary = Binary.new check_ctx_status(context) do mongocrypt_ctx_finalize(context.ctx_p, binary.ref) end # TODO since the binary references a C pointer, and ByteBuffer is # written in C in MRI, we could omit a copy of the data by making # ByteBuffer reference the string that is owned by libmongocrypt. BSON::Document.from_bson(BSON::ByteBuffer.new(binary.to_s), mode: :bson) end
Indicate to libmongocrypt that it will receive no more KMS replies.
@param [ Mongo::Crypt::Context
] context
@raise [ Mongo::Error::CryptError
] If the operation is unsuccessful
# File lib/mongo/crypt/binding.rb, line 989 def self.ctx_kms_done(context) check_ctx_status(context) do mongocrypt_ctx_kms_done(context.ctx_p) end end
Feed a response from the driver back to libmongocrypt
@param [ Mongo::Crypt::Context
] context @param [ BSON::Document ] doc The document representing the response
@raise [ Mongo::Error::CryptError
] If the response is not fed successfully
# File lib/mongo/crypt/binding.rb, line 808 def self.ctx_mongo_feed(context, doc) validate_document(doc) data = doc.to_bson.to_s Binary.wrap_string(data) do |data_p| check_ctx_status(context) do mongocrypt_ctx_mongo_feed(context.ctx_p, data_p) end end end
Returns a BSON::Document representing an operation that the driver must perform on behalf of libmongocrypt to get the information it needs in order to continue with encryption/decryption (for example, a filter for a key vault query).
@param [ Mongo::Crypt::Context
] context
@raise [ Mongo::Crypt
] If there is an error getting the operation @return [ BSON::Document ] The operation that the driver must perform
# File lib/mongo/crypt/binding.rb, line 779 def self.ctx_mongo_op(context) binary = Binary.new check_ctx_status(context) do mongocrypt_ctx_mongo_op(context.ctx_p, binary.ref) end # TODO since the binary references a C pointer, and ByteBuffer is # written in C in MRI, we could omit a copy of the data by making # ByteBuffer reference the string that is owned by libmongocrypt. BSON::Document.from_bson(BSON::ByteBuffer.new(binary.to_s), mode: :bson) end
Return a new KmsContext
object needed by a Context
object.
@param [ Mongo::Crypt::Context
] context
@return [ Mongo::Crypt::KmsContext
| nil ] The KmsContext
needed to
fetch an AWS master key or nil, if no KmsContext is needed
# File lib/mongo/crypt/binding.rb, line 840 def self.ctx_next_kms_ctx(context) kms_ctx_p = mongocrypt_ctx_next_kms_ctx(context.ctx_p) if kms_ctx_p.null? nil else KmsContext.new(kms_ctx_p) end end
Set the algorithm on the context
@param [ Mongo::Crypt::Context
] context @param [ String ] name The algorithm name. Valid values are:
- "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
@raise [ Mongo::Error::CryptError
] If the operation failed
# File lib/mongo/crypt/binding.rb, line 490 def self.ctx_setopt_algorithm(context, name) check_ctx_status(context) do mongocrypt_ctx_setopt_algorithm(context.ctx_p, name, -1) end end
Set multiple alternate key names on data key creation
@param [ Mongo::Crypt::Context
] context A DataKeyContext
@param [ Array ] key_alt_names An array of alternate key names as strings
@raise [ Mongo::Error::CryptError
] If any of the alternate names are
not valid UTF8 strings
# File lib/mongo/crypt/binding.rb, line 453 def self.ctx_setopt_key_alt_names(context, key_alt_names) key_alt_names.each do |key_alt_name| key_alt_name_bson = { :keyAltName => key_alt_name }.to_bson.to_s Binary.wrap_string(key_alt_name_bson) do |key_alt_name_p| check_ctx_status(context) do mongocrypt_ctx_setopt_key_alt_name(context.ctx_p, key_alt_name_p) end end end end
Sets the key id option on an explicit encryption context.
@param [ Mongo::Crypt::Context
] context Explicit encryption context @param [ String ] key_id The key id
@raise [ Mongo::Error::CryptError
] If the operation failed
# File lib/mongo/crypt/binding.rb, line 420 def self.ctx_setopt_key_id(context, key_id) Binary.wrap_string(key_id) do |key_id_p| check_ctx_status(context) do mongocrypt_ctx_setopt_key_id(context.ctx_p, key_id_p) end end end
Configure the Context
object to take a master key from AWS
@param [ Mongo::Crypt::Context
] context @param [ String ] region The AWS region (e.g. “us-east-2”) @param [ String ] arn The master key Amazon Resource Name
@raise [ Mongo::Error::CryptError
] If the operation failed
# File lib/mongo/crypt/binding.rb, line 521 def self.ctx_setopt_master_key_aws(context, region, arn) check_ctx_status(context) do mongocrypt_ctx_setopt_masterkey_aws( context.ctx_p, region, -1, arn, -1 ) end end
Configure the Context
object to take a masterk ey from AWS
@param [ Mongo::Crypt::Context
] context @param [ String ] endpoint The custom AWS master key endpoint
@raise [ Mongo::Error::CryptError
] If the operation failed
# File lib/mongo/crypt/binding.rb, line 554 def self.ctx_setopt_master_key_aws_endpoint(context, endpoint) check_ctx_status(context) do mongocrypt_ctx_setopt_masterkey_aws_endpoint( context.ctx_p, endpoint, -1, ) end end
Tell the Context
object to read the master key from local KMS options
@param [ Mongo::Crypt::Context
] context
@raise [ Mongo::Error::CryptError
] If the operation failed
# File lib/mongo/crypt/binding.rb, line 582 def self.ctx_setopt_master_key_local(context) check_ctx_status(context) do mongocrypt_ctx_setopt_masterkey_local(context.ctx_p) end end
Initialize the Mongo::Crypt::Handle
object
@param [ Mongo::Crypt::Handle
] handle
@raise [ Mongo::Error::CryptError
] If initialization fails
# File lib/mongo/crypt/binding.rb, line 360 def self.init(handle) check_status(handle) do mongocrypt_init(handle.ref) end end
Get the number of bytes needed by the KmsContext
.
@param [ Mongo::Crypt::KmsContext
] kms_context
@return [ Integer ] The number of bytes needed
# File lib/mongo/crypt/binding.rb, line 922 def self.kms_ctx_bytes_needed(kms_context) mongocrypt_kms_ctx_bytes_needed(kms_context.kms_ctx_p) end
Get the hostname with which to connect over TLS to get information about the AWS master key.
@param [ Mongo::Crypt::KmsContext
] kms_context
@raise [ Mongo::Error::CryptError
] If the response is not fed successfully
@return [ String | nil ] The hostname, or nil if none exists
# File lib/mongo/crypt/binding.rb, line 898 def self.kms_ctx_endpoint(kms_context) ptr = FFI::MemoryPointer.new(:pointer, 1) check_kms_ctx_status(kms_context) do mongocrypt_kms_ctx_endpoint(kms_context.kms_ctx_p, ptr) end str_ptr = ptr.read_pointer str_ptr.null? ? nil : str_ptr.read_string.force_encoding('UTF-8') end
Feed replies from the KMS back to libmongocrypt.
@param [ Mongo::Crypt::KmsContext
] kms_context @param [ String ] bytes The data to feed to libmongocrypt
@raise [ Mongo::Error::CryptError
] If the response is not fed successfully
# File lib/mongo/crypt/binding.rb, line 942 def self.kms_ctx_feed(kms_context, bytes) check_kms_ctx_status(kms_context) do Binary.wrap_string(bytes) do |bytes_p| mongocrypt_kms_ctx_feed(kms_context.kms_ctx_p, bytes_p) end end end
Get the HTTP message needed to fetch the AWS KMS master key from a KmsContext
object.
@param [ Mongo::Crypt::KmsContext
] kms_context
@raise [ Mongo::Error::CryptError
] If the response is not fed successfully
@return [ String ] The HTTP message
# File lib/mongo/crypt/binding.rb, line 869 def self.kms_ctx_message(kms_context) binary = Binary.new check_kms_ctx_status(kms_context) do mongocrypt_kms_ctx_message(kms_context.kms_ctx_p, binary.ref) end return binary.to_s end
Set crypto callbacks on the Handle
@param [ Mongo::Crypt::Handle
] handle @param [ Method ] aes_encrypt_cb An AES encryption method @param [ Method ] aes_decrypt_cb A AES decryption method @param [ Method ] random_cb A method that returns a string of random bytes @param [ Method ] hmac_sha_512_cb A HMAC SHA-512 method @param [ Method ] hmac_sha_256_cb A HMAC SHA-256 method @param [ Method ] hmac_hash_cb A SHA-256 hash method
@raise [ Mongo::Error::CryptError
] If the callbacks aren't set successfully
# File lib/mongo/crypt/binding.rb, line 1162 def self.setopt_crypto_hooks(handle, aes_encrypt_cb, aes_decrypt_cb, random_cb, hmac_sha_512_cb, hmac_sha_256_cb, hmac_hash_cb ) check_status(handle) do mongocrypt_setopt_crypto_hooks(handle.ref, aes_encrypt_cb, aes_decrypt_cb, random_cb, hmac_sha_512_cb, hmac_sha_256_cb, hmac_hash_cb, nil ) end end
Configure the Handle
object with AWS KMS provider options
@param [ Mongo::Crypt::Handle
] handle @param [ String ] aws_access_key The AWS access key @param [ String ] aws_secret_access_key The AWS secret access key
@raise [ Mongo::Error::CryptError
] If the option is not set successfully
# File lib/mongo/crypt/binding.rb, line 278 def self.setopt_kms_provider_aws(handle, aws_access_key, aws_secret_access_key ) check_status(handle) do mongocrypt_setopt_kms_provider_aws( handle.ref, aws_access_key, -1, aws_secret_access_key, -1 ) end end
Set local KMS provider options on the Mongo::Crypt::Handle
object
@param [ Mongo::Crypt::Handle
] handle @param [ String ] master_key The 96-byte local KMS master key
@raise [ Mongo::Error::CryptError
] If the option is not set successfully
# File lib/mongo/crypt/binding.rb, line 312 def self.setopt_kms_provider_local(handle, master_key) Binary.wrap_string(master_key) do |master_key_p| check_status(handle) do mongocrypt_setopt_kms_provider_local(handle.ref, master_key_p) end end end
Set the logger callback function on the Mongo::Crypt::Handle
object
@param [ Mongo::Crypt::Handle
] handle @param [ Method ] log_callback
@raise [ Mongo::Error::CryptError
] If the callback is not set successfully
# File lib/mongo/crypt/binding.rb, line 247 def self.setopt_log_handler(handle, log_callback) check_status(handle) do mongocrypt_setopt_log_handler(handle, log_callback, nil) end end
Set schema map on the Mongo::Crypt::Handle
object
@param [ Mongo::Crypt::Handle
] handle @param [ BSON::Document ] schema_map_doc The schema map as a
BSON::Document object
@raise [ Mongo::Error::CryptError
] If the schema map is not set successfully
# File lib/mongo/crypt/binding.rb, line 337 def self.setopt_schema_map(handle, schema_map_doc) validate_document(schema_map_doc) data = schema_map_doc.to_bson.to_s Binary.wrap_string(data) do |data_p| check_status(handle) do mongocrypt_setopt_schema_map(handle.ref, data_p) end end end
Checks that the specified data is a Hash before serializing it to BSON to prevent errors from libmongocrypt
@note All BSON::Document instances are also Hash instances
@param [ Object ] data The data to be passed to libmongocrypt
@raise [ Mongo::Error::CryptError
] If the data is not a Hash
# File lib/mongo/crypt/binding.rb, line 1214 def self.validate_document(data) return if data.is_a?(Hash) if data.nil? message = "Attempted to pass nil data to libmongocrypt. " + "Data must be a Hash" else message = "Attempted to pass invalid data to libmongocrypt: #{data} " + "Data must be a Hash" end raise Error::CryptError.new(message) end