Class: Mongo::Crypt::ExplicitEncrypter Private

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/mongo/crypt/explicit_encrypter.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

An ExplicitEncrypter is an object that performs explicit encryption operations and handles all associated options and instance variables.

Instance Method Summary collapse

Constructor Details

#initialize(key_vault_client, key_vault_namespace, kms_providers, kms_tls_options, timeout_ms = nil) ⇒ ExplicitEncrypter

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a new ExplicitEncrypter object.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 40

def initialize(key_vault_client, key_vault_namespace, kms_providers, kms_tls_options, timeout_ms = nil)
  Crypt.validate_ffi!
  @crypt_handle = Handle.new(
    kms_providers,
    kms_tls_options,
    explicit_encryption_only: true
  )
  @encryption_io = EncryptionIO.new(
    key_vault_client: key_vault_client,
    metadata_client: nil,
    key_vault_namespace: key_vault_namespace
  )
  @timeout_ms = timeout_ms
end

Instance Method Details

#add_key_alt_name(id, key_alt_name) ⇒ BSON::Document | nil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Adds a key_alt_name for the key in the key vault collection with the given id.



203
204
205
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 203

def add_key_alt_name(id, key_alt_name)
  @encryption_io.add_key_alt_name(id, key_alt_name, timeout_ms: @timeout_ms)
end

#create_and_insert_data_key(master_key_document, key_alt_names, key_material = nil) ⇒ BSON::Binary

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Generates a data key used for encryption/decryption and stores that key in the KMS collection. The generated key is encrypted with the KMS master key.



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 70

def create_and_insert_data_key(master_key_document, key_alt_names, key_material = nil)
  data_key_document = Crypt::DataKeyContext.new(
    @crypt_handle,
    @encryption_io,
    master_key_document,
    key_alt_names,
    key_material
  ).run_state_machine(timeout_holder)

  @encryption_io.insert_data_key(
    data_key_document, timeout_ms: timeout_holder.remaining_timeout_ms!
  ).inserted_id
end

#decrypt(value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Decrypts a value that has already been encrypted



188
189
190
191
192
193
194
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 188

def decrypt(value)
  Crypt::ExplicitDecryptionContext.new(
    @crypt_handle,
    @encryption_io,
    { v: value }
  ).run_state_machine(timeout_holder)['v']
end

#delete_key(id) ⇒ Operation::Result

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Removes the key with the given id from the key vault collection.



213
214
215
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 213

def delete_key(id)
  @encryption_io.delete_key(id, timeout_ms: @timeout_ms)
end

#encrypt(value, options) ⇒ BSON::Binary

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

The :key_id and :key_alt_name options are mutually exclusive. Only one is required to perform explicit encryption.

Encrypts a value using the specified encryption key and algorithm

if encryption algorithm is set to “Indexed”. Query type should be set

only if encryption algorithm is set to "Indexed". The only allowed
value is "equality".

Options Hash (options):

  • :key_id (BSON::Binary)

    A BSON::Binary object of type :uuid representing the UUID of the encryption key as it is stored in the key vault collection.

  • :key_alt_name (String)

    The alternate name for the encryption key.

  • :algorithm (String)

    The algorithm used to encrypt the value. Valid algorithms are “AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic”, “AEAD_AES_256_CBC_HMAC_SHA_512-Random”, “Indexed”, “Unindexed”.

  • :contention_factor (Integer | nil)

    Contention factor to be applied if encryption algorithm is set to “Indexed”. If not provided, it defaults to a value of 0. Contention factor should be set only if encryption algorithm is set to “Indexed”.

  • query_type (String | nil)

    Query type to be applied

Raises:

  • (ArgumentError)

    if either contention_factor or query_type is set, and algorithm is not “Indexed”.



113
114
115
116
117
118
119
120
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 113

def encrypt(value, options)
  Crypt::ExplicitEncryptionContext.new(
    @crypt_handle,
    @encryption_io,
    { v: value },
    options
  ).run_state_machine(timeout_holder)['v']
end

#encrypt_expression(expression, options) ⇒ BSON::Binary

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

The Range algorithm is experimental only. It is not

Note:

The :key_id and :key_alt_name options are mutually exclusive. Only one is required to perform explicit encryption.

Encrypts a Match Expression or Aggregate Expression to query a range index.

Only supported when queryType is “range” and algorithm is “Range”. @note: The Range algorithm is experimental only. It is not intended

for public use. It is subject to breaking changes.

# @param [ Hash ] options intended for public use.

Examples:

Encrypt Match Expression.

encryption.encrypt_expression(
  {'$and' =>  [{'field' => {'$gt' => 10}}, {'field' =>  {'$lt' => 20 }}]}
)

Encrypt Aggregate Expression.

encryption.encrypt_expression(
  {'$and' =>  [{'$gt' => ['$field', 10]}, {'$lt' => ['$field', 20]}}
)
{$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]

Options Hash (options):

  • :key_id (BSON::Binary)

    A BSON::Binary object of type :uuid representing the UUID of the encryption key as it is stored in the key vault collection.

  • :key_alt_name (String)

    The alternate name for the encryption key.

  • :algorithm (String)

    The algorithm used to encrypt the expression. The only allowed value is “Range”

  • :contention_factor (Integer | nil)

    Contention factor to be applied If not provided, it defaults to a value of 0.

  • query_type (String | nil)

    Query type to be applied. The only allowed value is “range”.

  • :range_opts (Hash | nil)

    Specifies index options for a Queryable Encryption field supporting “range” queries. Allowed options are:

    • :min

    • :max

    • :trim_factor

    • :sparsity

    • :precision

    min, max, trim_factor, sparsity, and precision must match the values set in the encryptedFields of the destination collection. For double and decimal128, min/max/precision must all be set, or all be unset.

Raises:

  • (ArgumentError)

    if disallowed values in options are set.



173
174
175
176
177
178
179
180
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 173

def encrypt_expression(expression, options)
  Crypt::ExplicitEncryptionExpressionContext.new(
    @crypt_handle,
    @encryption_io,
    { v: expression },
    options
  ).run_state_machine(timeout_holder)['v']
end

#get_key(id) ⇒ BSON::Document | nil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Finds a single key with the given id.



223
224
225
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 223

def get_key(id)
  @encryption_io.get_key(id, timeout_ms: @timeout_ms)
end

#get_key_by_alt_name(key_alt_name) ⇒ BSON::Document | nil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a key in the key vault collection with the given key_alt_name.



233
234
235
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 233

def get_key_by_alt_name(key_alt_name)
  @encryption_io.get_key_by_alt_name(key_alt_name, timeout_ms: @timeout_ms)
end

#get_keysCollection::View

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns all keys in the key vault collection.

rubocop:disable Naming/AccessorMethodName Name of this method is defined in the FLE spec



242
243
244
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 242

def get_keys
  @encryption_io.get_keys(timeout_ms: @timeout_ms)
end

#remove_key_alt_name(id, key_alt_name) ⇒ BSON::Document | nil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Removes a key_alt_name from a key in the key vault collection with the given id.



254
255
256
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 254

def remove_key_alt_name(id, key_alt_name)
  @encryption_io.remove_key_alt_name(id, key_alt_name, timeout_ms: @timeout_ms)
end

#rewrap_many_data_key(filter, opts = {}) ⇒ Crypt::RewrapManyDataKeyResult

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Decrypts multiple data keys and (re-)encrypts them with a new master_key,

or with their current master_key if a new one is not given.


269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 269

def rewrap_many_data_key(filter, opts = {})
  validate_rewrap_options!(opts)

  master_key_document = master_key_for_provider(opts)

  rewrap_result = Crypt::RewrapManyDataKeyContext.new(
    @crypt_handle,
    @encryption_io,
    filter,
    master_key_document
  ).run_state_machine(timeout_holder)

  return RewrapManyDataKeyResult.new(nil) if rewrap_result.nil?

  updates = updates_from_data_key_documents(rewrap_result.fetch('v'))
  RewrapManyDataKeyResult.new(
    @encryption_io.update_data_keys(updates, timeout_ms: @timeout_ms)
  )
end