123456789_123456789_123456789_123456789_123456789_

Class: Mongo::Crypt::Context Private

Do not use. This class is for internal use only.
Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Mongo::Crypt::AutoDecryptionContext, Mongo::Crypt::AutoEncryptionContext, Mongo::Crypt::DataKeyContext, Mongo::Crypt::ExplicitDecryptionContext, Mongo::Crypt::ExplicitEncryptionContext, Mongo::Crypt::ExplicitEncryptionExpressionContext, Mongo::Crypt::RewrapManyDataKeyContext
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Forwardable
Inherits: Object
Defined in: lib/mongo/crypt/context.rb

Overview

A wrapper around mongocrypt_ctx_t, which manages the state machine for encryption and decription.

This class is a superclass that defines shared methods amongst contexts that are initialized for different purposes (e.g. data key creation, encryption, explicit encryption, etc.)

Class Method Summary

Instance Attribute Summary

  • #ctx_p readonly Internal use only

Instance Method Summary

Instance Attribute Details

#ctx_p (readonly)

[ GitHub ]

  
# File 'lib/mongo/crypt/context.rb', line 57

attr_reader :ctx_p

Instance Method Details

#azure_access_tokenString (private)

Returns an Azure access token, retrieving it if necessary.

Returns:

  • (String)

    An Azure access token.

Raises:

[ GitHub ]

  
# File 'lib/mongo/crypt/context.rb', line 192

def azure_access_token
  if @cached_azure_token.nil? || @cached_azure_token.expired?
    @cached_azure_token = KMS::Azure::CredentialsRetriever.fetch_access_token
  end
  @cached_azure_token.access_token
rescue KMS::CredentialsNotFound => e
  raise Error::CryptError.new(
    "Could not locate Azure credentials: #{e.class}: #{e.message}"
  )
end

#gcp_access_tokenString (private)

Retrieves a GCP access token.

Returns:

  • (String)

    A GCP access token.

Raises:

[ GitHub ]

  
# File 'lib/mongo/crypt/context.rb', line 178

def gcp_access_token
  KMS::GCP::CredentialsRetriever.fetch_access_token
rescue KMS::CredentialsNotFound => e
  raise Error::CryptError.new(
    "Could not locate GCP credentials: #{e.class}: #{e.message}"
  )
end

#mongocrypt_done (private)

Indicate that state machine is done feeding I/O responses back to libmongocrypt

[ GitHub ]

  
# File 'lib/mongo/crypt/context.rb', line 134

def mongocrypt_done
  Binding.mongocrypt_ctx_mongo_done(ctx_p)
end

#mongocrypt_feed(doc) ⇒ BSON::Document (private)

Feeds the result of a ::Mongo operation back to libmongocrypt.

Parameters:

  • doc (Hash)

    BSON document to feed.

Returns:

  • (BSON::Document)

    BSON document containing the result.

[ GitHub ]

  
# File 'lib/mongo/crypt/context.rb', line 143

def mongocrypt_feed(doc)
  Binding.ctx_mongo_feed(self, doc)
end

#retrieve_kms_credentialsCrypt::KMS::Credentials (private)

Retrieves KMS credentials for providers that are configured for automatic credentials retrieval.

Returns:

[ GitHub ]

  
# File 'lib/mongo/crypt/context.rb', line 152

def retrieve_kms_credentials
  providers = {}
  if kms_providers.aws&.empty?
    begin
      aws_credentials = Mongo::Auth::Aws::CredentialsRetriever.new.credentials
    rescue Auth::Aws::CredentialsNotFound
      raise Error::CryptError.new(
        "Could not locate AWS credentials (checked environment variables, ECS and EC2 metadata)"
      )
    end
    providers[:aws] = aws_credentials.to_h
  end
  if kms_providers.gcp&.empty?
    providers[:gcp] = { access_token: gcp_access_token }
  end
  if kms_providers.azure&.empty?
    providers[:azure] = { access_token: azure_access_token }
  end
  KMS::Credentials.new(providers)
end

#run_state_machineBSON::Document

Runs the mongocrypt_ctx_t state machine and handles all I/O on behalf of libmongocrypt

This method is not currently unit tested. It is integration tested in spec/integration/explicit_encryption_spec.rb

Returns:

  • (BSON::Document)

    A BSON document representing the outcome of the state machine. Contents can differ depending on how the context was initialized..

Raises:

[ GitHub ]

  
# File 'lib/mongo/crypt/context.rb', line 78

def run_state_machine
  while true
    case state
    when :error
      Binding.check_ctx_status(self)
    when :ready
      # Finalize the state machine and return the result as a BSON::Document
      return Binding.ctx_finalize(self)
    when :done
      return nil
    when :need_mongo_keys
      filter = Binding.ctx_mongo_op(self)

      @encryption_io.find_keys(filter).each do |key|
        mongocrypt_feed(key) if key
      end

      mongocrypt_done
    when :need_mongo_collinfo
      filter = Binding.ctx_mongo_op(self)

      result = @encryption_io.collection_info(@db_name, filter)
      mongocrypt_feed(result) if result

      mongocrypt_done
    when :need_mongo_markings
      cmd = Binding.ctx_mongo_op(self)

      result = @encryption_io.mark_command(cmd)
      mongocrypt_feed(result)

      mongocrypt_done
    when :need_kms
      while kms_context = Binding.ctx_next_kms_ctx(self) do
        provider = Binding.kms_ctx_get_kms_provider(kms_context)
        tls_options = @mongocrypt_handle.kms_tls_options(provider)
        @encryption_io.feed_kms(kms_context, tls_options)
      end

      Binding.ctx_kms_done(self)
    when :need_kms_credentials
      Binding.ctx_provide_kms_providers(
        self,
        retrieve_kms_credentials.to_document
      )
    else
      raise Error::CryptError.new(
        "State #{state} is not supported by Mongo::Crypt::Context"
      )
    end
  end
end

#stateSymbol

Returns the state of the mongocrypt_ctx_t

Returns:

  • (Symbol)

    The context state

[ GitHub ]

  
# File 'lib/mongo/crypt/context.rb', line 62

def state
  Binding.mongocrypt_ctx_state(@ctx_p)
end