Class: Mongo::Crypt::EncryptionIO Private

Inherits:
Object
  • Object
show all
Defined in:
build/ruby-driver-master/lib/mongo/crypt/encryption_io.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.

A class that implements I/O methods between the driver and the MongoDB server or mongocryptd.

Constant Summary collapse

SOCKET_TIMEOUT =

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

Timeout used for TLS socket connection, reading, and writing. There is no specific timeout written in the spec. See SPEC-1394 for a discussion and updates on what this timeout should be.

10

Instance Method Summary collapse

Constructor Details

#initialize(client: nil, mongocryptd_client: nil, key_vault_namespace:, key_vault_client:, mongocryptd_options: {}) ⇒ EncryptionIO

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:

When being used for auto encryption, all arguments are required. When being used for explicit encryption, only the key_vault_namespace and key_vault_client arguments are required.

Note:

This class expects that the key_vault_client and key_vault_namespace options are not nil and are in the correct format.

Creates a new EncryptionIO object with information about how to connect to the key vault.

Parameters:

  • client (Mongo::Client) (defaults to: nil)

    The client used to connect to the collection that stores the encrypted documents, defaults to nil.

  • mongocryptd_client (Mongo::Client) (defaults to: nil)

    The client connected to mongocryptd, defaults to nil.

  • key_vault_client (Mongo::Client)

    The client connected to the key vault collection.

  • key_vault_namespace (String)

    The key vault namespace in the format db_name.collection_name.

  • mongocryptd_options (Hash) (defaults to: {})

    Options related to mongocryptd.

Options Hash (mongocryptd_options:):

  • :mongocryptd_bypass_spawn (Boolean)
  • :mongocryptd_spawn_path (String)
  • :mongocryptd_spawn_args (Array<String>)


55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'build/ruby-driver-master/lib/mongo/crypt/encryption_io.rb', line 55

def initialize(
  client: nil, mongocryptd_client: nil, key_vault_namespace:,
  key_vault_client:, mongocryptd_options: {}
)
  validate_key_vault_client!(key_vault_client)
  validate_key_vault_namespace!(key_vault_namespace)

  @client = client
  @mongocryptd_client = mongocryptd_client
  @key_vault_db_name, @key_vault_collection_name = key_vault_namespace.split('.')
  @key_vault_client = key_vault_client
  @options = mongocryptd_options
end

Instance Method Details

#collection_info(db_name, filter) ⇒ Hash

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.

Get collection info for a collection matching the provided filter

Parameters:

  • filter (Hash)

Returns:

  • (Hash)

    The collection information



93
94
95
96
97
98
99
# File 'build/ruby-driver-master/lib/mongo/crypt/encryption_io.rb', line 93

def collection_info(db_name, filter)
  unless @client
    raise ArgumentError, 'collection_info requires client to have been passed to the constructor, but it was not'
  end

  @client.use(db_name).database.list_collections(filter: filter).first
end

#feed_kms(kms_context) ⇒ 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.

Get information about the AWS encryption key and feed it to the the KmsContext object

Parameters:

  • kms_context (Mongo::Crypt::KmsContext)

    A KmsContext object corresponding to one AWS KMS data key. Contains information about the endpoint at which to establish a TLS connection and the message to send on that connection.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'build/ruby-driver-master/lib/mongo/crypt/encryption_io.rb', line 134

def feed_kms(kms_context)
  with_ssl_socket(kms_context.endpoint) do |ssl_socket|

    Timeout.timeout(SOCKET_TIMEOUT, Error::SocketTimeoutError,
      'Socket write operation timed out'
    ) do
      ssl_socket.syswrite(kms_context.message)
    end

    bytes_needed = kms_context.bytes_needed
    while bytes_needed > 0 do
      bytes = Timeout.timeout(SOCKET_TIMEOUT, Error::SocketTimeoutError,
        'Socket read operation timed out'
      ) do
        ssl_socket.sysread(bytes_needed)
      end

      kms_context.feed(bytes)
      bytes_needed = kms_context.bytes_needed
    end
  end
end

#find_keys(filter) ⇒ Array<BSON::Document>

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.

Query for keys in the key vault collection using the provided filter

Parameters:

  • filter (Hash)

Returns:

  • (Array<BSON::Document>)

    The query results



75
76
77
# File 'build/ruby-driver-master/lib/mongo/crypt/encryption_io.rb', line 75

def find_keys(filter)
  key_vault_collection.find(filter).to_a
end

#insert_data_key(document) ⇒ Mongo::Operation::Insert::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.

Insert a document into the key vault collection

Parameters:

  • document (Hash)

Returns:



84
85
86
# File 'build/ruby-driver-master/lib/mongo/crypt/encryption_io.rb', line 84

def insert_data_key(document)
  key_vault_collection.insert_one(document)
end

#mark_command(cmd) ⇒ Hash

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.

Send the command to mongocryptd to be marked with intent-to-encrypt markings

Parameters:

  • cmd (Hash)

Returns:

  • (Hash)

    The marked command



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'build/ruby-driver-master/lib/mongo/crypt/encryption_io.rb', line 106

def mark_command(cmd)
  unless @mongocryptd_client
    raise ArgumentError, 'mark_command requires mongocryptd_client to have been passed to the constructor, but it was not'
  end

  # Ensure the response from mongocryptd is deserialized with { mode: :bson }
  # to prevent losing type information in commands
  options = { execution_options: { deserialize_as_bson: true } }

  begin
    response = @mongocryptd_client.database.command(cmd, options)
  rescue Error::NoServerAvailable => e
    raise e if @options[:mongocryptd_bypass_spawn]

    spawn_mongocryptd
    response = @mongocryptd_client.database.command(cmd, options)
  end

  return response.first
end