1
1
# frozen_string_literal: true
2
- # rubocop:todo all
3
2
4
3
# Copyright (C) 2020 MongoDB Inc.
5
4
#
17
16
18
17
module Mongo
19
18
module Crypt
20
-
21
19
# An ExplicitEncrypter is an object that performs explicit encryption
22
20
# operations and handles all associated options and instance variables.
23
21
#
24
22
# @api private
25
23
class ExplicitEncrypter
24
+ extend Forwardable
25
+
26
26
# Create a new ExplicitEncrypter object.
27
27
#
28
28
# @param [ Mongo::Client ] key_vault_client An instance of Mongo::Client
@@ -44,7 +44,7 @@ def initialize(key_vault_client, key_vault_namespace, kms_providers, kms_tls_opt
44
44
@encryption_io = EncryptionIO . new (
45
45
key_vault_client : key_vault_client ,
46
46
metadata_client : nil ,
47
- key_vault_namespace : key_vault_namespace ,
47
+ key_vault_namespace : key_vault_namespace
48
48
)
49
49
end
50
50
@@ -108,7 +108,7 @@ def encrypt(value, options)
108
108
Crypt ::ExplicitEncryptionContext . new (
109
109
@crypt_handle ,
110
110
@encryption_io ,
111
- { 'v' : value } ,
111
+ { v : value } ,
112
112
options
113
113
) . run_state_machine [ 'v' ]
114
114
end
@@ -167,7 +167,7 @@ def encrypt_expression(expression, options)
167
167
Crypt ::ExplicitEncryptionExpressionContext . new (
168
168
@crypt_handle ,
169
169
@encryption_io ,
170
- { 'v' : expression } ,
170
+ { v : expression } ,
171
171
options
172
172
) . run_state_machine [ 'v' ]
173
173
end
@@ -179,10 +179,10 @@ def encrypt_expression(expression, options)
179
179
#
180
180
# @return [ Object ] The decrypted value
181
181
def decrypt ( value )
182
- result = Crypt ::ExplicitDecryptionContext . new (
182
+ Crypt ::ExplicitDecryptionContext . new (
183
183
@crypt_handle ,
184
184
@encryption_io ,
185
- { 'v' : value } ,
185
+ { v : value }
186
186
) . run_state_machine [ 'v' ]
187
187
end
188
188
@@ -203,36 +203,28 @@ def add_key_alt_name(id, key_alt_name)
203
203
#
204
204
# @return [ Operation::Result ] The response from the database for the delete_one
205
205
# operation that deletes the key.
206
- def delete_key ( id )
207
- @encryption_io . delete_key ( id )
208
- end
206
+ def_delegators :@encryption_io , :delete_key
209
207
210
208
# Finds a single key with the given id.
211
209
#
212
210
# @param [ BSON::Binary ] id Id of the key to get.
213
211
#
214
212
# @return [ BSON::Document | nil ] The found key document or nil
215
213
# if not found.
216
- def get_key ( id )
217
- @encryption_io . get_key ( id )
218
- end
214
+ def_delegators :@encryption_io , :get_key
219
215
220
216
# Returns a key in the key vault collection with the given key_alt_name.
221
217
#
222
218
# @param [ String ] key_alt_name Key alt name to find a key.
223
219
#
224
220
# @return [ BSON::Document | nil ] The found key document or nil
225
221
# if not found.
226
- def get_key_by_alt_name ( key_alt_name )
227
- @encryption_io . get_key_by_alt_name ( key_alt_name )
228
- end
222
+ def_delegators :@encryption_io , :get_key_by_alt_name
229
223
230
224
# Returns all keys in the key vault collection.
231
225
#
232
226
# @return [ Collection::View ] Keys in the key vault collection.
233
- def get_keys
234
- @encryption_io . get_keys
235
- end
227
+ def_delegators :@encryption_io , :get_keys
236
228
237
229
# Removes a key_alt_name from a key in the key vault collection with the given id.
238
230
#
@@ -241,9 +233,7 @@ def get_keys
241
233
#
242
234
# @return [ BSON::Document | nil ] Document describing the identified key
243
235
# before removing the key alt name, or nil if no such key.
244
- def remove_key_alt_name ( id , key_alt_name )
245
- @encryption_io . remove_key_alt_name ( id , key_alt_name )
246
- end
236
+ def_delegators :@encryption_io , :remove_key_alt_name
247
237
248
238
# Decrypts multiple data keys and (re-)encrypts them with a new master_key,
249
239
# or with their current master_key if a new one is not given.
@@ -259,23 +249,60 @@ def remove_key_alt_name(id, key_alt_name)
259
249
def rewrap_many_data_key ( filter , opts = { } )
260
250
validate_rewrap_options! ( opts )
261
251
262
- master_key_document = if opts [ :provider ]
263
- options = opts . dup
264
- provider = options . delete ( :provider )
265
- KMS ::MasterKeyDocument . new ( provider , options )
266
- end
252
+ master_key_document = master_key_for_provider ( opts )
267
253
268
254
rewrap_result = Crypt ::RewrapManyDataKeyContext . new (
269
255
@crypt_handle ,
270
256
@encryption_io ,
271
257
filter ,
272
258
master_key_document
273
259
) . run_state_machine
274
- if rewrap_result . nil?
275
- return RewrapManyDataKeyResult . new ( nil )
276
- end
277
- data_key_documents = rewrap_result . fetch ( 'v' )
278
- updates = data_key_documents . map do |doc |
260
+
261
+ return RewrapManyDataKeyResult . new ( nil ) if rewrap_result . nil?
262
+
263
+ updates = updates_from_data_key_documents ( rewrap_result . fetch ( 'v' ) )
264
+ RewrapManyDataKeyResult . new ( @encryption_io . update_data_keys ( updates ) )
265
+ end
266
+
267
+ private
268
+
269
+ # Ensures the consistency of the options passed to #rewrap_many_data_keys.
270
+ #
271
+ # @param [ Hash ] opts the options hash to validate
272
+ #
273
+ # @raise [ ArgumentError ] if the options are not consistent or
274
+ # compatible.
275
+ def validate_rewrap_options! ( opts )
276
+ return unless opts . key? ( :master_key ) && !opts . key? ( :provider )
277
+
278
+ raise ArgumentError , 'If :master_key is specified, :provider must also be given'
279
+ end
280
+
281
+ # If a :provider is given, construct a new master key document
282
+ # with that provider.
283
+ #
284
+ # @param [ Hash ] opts the options hash
285
+ #
286
+ # @option [ String ] :provider KMS provider to encrypt keys.
287
+ #
288
+ # @return [ KMS::MasterKeyDocument | nil ] the new master key document,
289
+ # or nil if no provider was given.
290
+ def master_key_for_provider ( opts )
291
+ return nil unless opts [ :provider ]
292
+
293
+ options = opts . dup
294
+ provider = options . delete ( :provider )
295
+ KMS ::MasterKeyDocument . new ( provider , options )
296
+ end
297
+
298
+ # Returns the corresponding update document for each for of the given
299
+ # data key documents.
300
+ #
301
+ # @param [ Array<Hash> ] documents the data key documents
302
+ #
303
+ # @return [ Array<Hash> ] the update documents
304
+ def updates_from_data_key_documents ( documents )
305
+ documents . map do |doc |
279
306
{
280
307
update_one : {
281
308
filter : { _id : doc [ :_id ] } ,
@@ -289,21 +316,6 @@ def rewrap_many_data_key(filter, opts = {})
289
316
}
290
317
}
291
318
end
292
- RewrapManyDataKeyResult . new (
293
- @encryption_io . update_data_keys ( updates )
294
- )
295
- end
296
-
297
- # Ensures the consistency of the options passed to #rewrap_many_data_keys.
298
- #
299
- # @param [Hash] opts the options hash to validate
300
- #
301
- # @raise [ ArgumentError ] if the options are not consistent or
302
- # compatible.
303
- def validate_rewrap_options! ( opts )
304
- if opts . key? ( :master_key ) && !opts . key? ( :provider )
305
- raise ArgumentError , 'If :master_key is specified, :provider must also be given'
306
- end
307
319
end
308
320
end
309
321
end
0 commit comments