123456789_123456789_123456789_123456789_123456789_

Class: Mongo::Crypt::ExplicitEncrypter Private

Do not use. This class is for internal use only.
Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Forwardable
Inherits: Object
Defined in: lib/mongo/crypt/explicit_encrypter.rb

Overview

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

Class Method Summary

Instance Method Summary

Instance Method Details

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

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

Parameters:

  • id (BSON::Binary)

    ::Mongo::Id of the key to add new key alt name.

  • key_alt_name (String)

    New key alt name to add.

Returns:

  • (BSON::Document | nil)

    Document describing the identified key before adding the key alt name, or nil if no such key.

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 197

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

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

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.

Parameters:

  • master_key_document (Mongo::Crypt::KMS::MasterKeyDocument)

    The master key document that contains master encryption key parameters.

  • key_alt_names (Array<String> | nil)

    An optional array of strings specifying alternate names for the new data key.

  • key_material (String | nil) (defaults to: nil)

    Optional 96 bytes to use as custom key material for the data key being created. If key_material option is given, the custom key material is used for encrypting and decrypting data.

Returns:

  • (BSON::Binary)

    The 16-byte UUID of the new data key as a BSON::Binary object with type :uuid.

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 67

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

  @encryption_io.insert_data_key(data_key_document).inserted_id
end

#decrypt(value) ⇒ Object

Decrypts a value that has already been encrypted

Parameters:

  • value (BSON::Binary)

    A BSON Binary object of subtype 6 (ciphertext) that will be decrypted

Returns:

  • (Object)

    The decrypted value

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 182

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

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

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".

Parameters:

  • value (Object)

    The value to encrypt

  • options (Hash)

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

Returns:

  • (BSON::Binary)

    A BSON Binary object of subtype 6 (ciphertext) representing the encrypted value

Raises:

  • (ArgumentError)

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

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 108

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

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

Note:

The RangePreview 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 “rangePreview” and algorithm is “RangePreview”. @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>]}]

Parameters:

  • expression (Hash)

    Expression to encrypt.

  • options (Hash)

    a customizable set of options

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 “RangePreview”

  • :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 “rangePreview”.

  • :range_opts (Hash | nil)

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

    • :min

    • :max

    • :sparsity

    • :precision

    min, max, sparsity, and range 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.

Returns:

  • (BSON::Binary)

    A BSON Binary object of subtype 6 (ciphertext) representing the encrypted expression.

Raises:

  • (ArgumentError)

    if disallowed values in options are set.

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 167

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

#master_key_for_provider(opts) ⇒ KMS::MasterKeyDocument | nil (private)

If a :provider is given, construct a new master key document with that provider.

Parameters:

  • opts (Hash)

    the options hash

  • [ (Hash)

    a customizable set of options

Returns:

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 291

def master_key_for_provider(opts)
  return nil unless opts[:provider]

  options = opts.dup
  provider = options.delete(:provider)
  KMS::MasterKeyDocument.new(provider, options)
end

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

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.

Parameters:

  • filter (Hash)

    Filter used to find keys to be updated.

  • options (Hash)

Returns:

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 250

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

  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))
end

#updates_from_data_key_documents(documents) ⇒ Array<Hash> (private)

Returns the corresponding update document for each for of the given data key documents.

Parameters:

  • documents (Array<Hash>)

    the data key documents

Returns:

  • (Array<Hash>)

    the update documents

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 305

def updates_from_data_key_documents(documents)
  documents.map do |doc|
    {
      update_one: {
        filter: { _id: doc[:_id] },
        update: {
          '$set' => {
            masterKey: doc[:masterKey],
            keyMaterial: doc[:keyMaterial]
          },
          '$currentDate' => { updateDate: true },
        },
      }
    }
  end
end

#validate_rewrap_options!(opts) (private)

Ensures the consistency of the options passed to #rewrap_many_data_keys.

Parameters:

  • opts (Hash)

    the options hash to validate

Raises:

  • (ArgumentError)

    if the options are not consistent or compatible.

[ GitHub ]

  
# File 'lib/mongo/crypt/explicit_encrypter.rb', line 276

def validate_rewrap_options!(opts)
  return unless opts.key?(:master_key) && !opts.key?(:provider)

  raise ArgumentError, 'If :master_key is specified, :provider must also be given'
end