izokatu 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +2 -0
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/.rubocop.yml +42 -0
- data/.yardopts +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +86 -0
- data/LICENSE.txt +21 -0
- data/README.md +152 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/certs/mongalless.pem +26 -0
- data/izokatu.gemspec +47 -0
- data/lib/izokatu.rb +423 -0
- data/lib/izokatu/action_call_options_selector.rb +214 -0
- data/lib/izokatu/action_call_selector.rb +132 -0
- data/lib/izokatu/callable.rb +13 -0
- data/lib/izokatu/ciphers.rb +18 -0
- data/lib/izokatu/decrypter.rb +62 -0
- data/lib/izokatu/encrypter.rb +67 -0
- data/lib/izokatu/exporter.rb +36 -0
- data/lib/izokatu/exporter/file_exporter.rb +36 -0
- data/lib/izokatu/exporter/function_exporter.rb +16 -0
- data/lib/izokatu/exporter/stdout_exporter.rb +18 -0
- data/lib/izokatu/helpers.rb +213 -0
- data/lib/izokatu/importer/file_importer.rb +47 -0
- data/lib/izokatu/importer/function_importer.rb +36 -0
- data/lib/izokatu/izokatu_elements_requires.rb +46 -0
- data/lib/izokatu/keys_generator.rb +53 -0
- data/lib/izokatu/openssl/private_key/auth/ccm/decrypter.rb +67 -0
- data/lib/izokatu/openssl/private_key/auth/ccm/encrypter.rb +56 -0
- data/lib/izokatu/openssl/private_key/auth/decrypter.rb +79 -0
- data/lib/izokatu/openssl/private_key/auth/encrypter.rb +69 -0
- data/lib/izokatu/openssl/private_key/default/decrypter.rb +75 -0
- data/lib/izokatu/openssl/private_key/default/encrypter.rb +75 -0
- data/lib/izokatu/openssl/public_key/ec/decrypter.rb +105 -0
- data/lib/izokatu/openssl/public_key/ec/encrypter.rb +106 -0
- data/lib/izokatu/openssl/public_key/ec/keys_generator.rb +77 -0
- data/lib/izokatu/openssl/public_key/rsa/decrypter.rb +53 -0
- data/lib/izokatu/openssl/public_key/rsa/encrypter.rb +55 -0
- data/lib/izokatu/openssl/public_key/rsa/keys_generator.rb +64 -0
- data/lib/izokatu/rbnacl/decrypter.rb +42 -0
- data/lib/izokatu/rbnacl/encrypter.rb +45 -0
- data/lib/izokatu/rbnacl/private_key/decrypter.rb +56 -0
- data/lib/izokatu/rbnacl/private_key/encrypter.rb +61 -0
- data/lib/izokatu/rbnacl/public_key/decrypter.rb +51 -0
- data/lib/izokatu/rbnacl/public_key/encrypter.rb +61 -0
- data/lib/izokatu/rbnacl/public_key/keys_generator.rb +33 -0
- data/lib/izokatu/version.rb +6 -0
- metadata +315 -0
- metadata.gz.sig +0 -0
data/lib/izokatu.rb
ADDED
@@ -0,0 +1,423 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
require 'rbnacl'
|
5
|
+
require 'ecies'
|
6
|
+
require 'base64'
|
7
|
+
|
8
|
+
require 'contracts'
|
9
|
+
# Deprecated warnings are disabled, because contracts raising those.
|
10
|
+
# Make patch to contracts or use more updated tools, like, Sorbet.
|
11
|
+
Warning[:deprecated] = false
|
12
|
+
|
13
|
+
require_relative 'izokatu/izokatu_elements_requires'
|
14
|
+
|
15
|
+
# Main module to work with.
|
16
|
+
module Izokatu
|
17
|
+
include Contracts
|
18
|
+
|
19
|
+
class << self
|
20
|
+
prepend Izokatu::Helpers
|
21
|
+
|
22
|
+
# @return [Symbol] library used for encryption/decryption
|
23
|
+
attr_reader :via
|
24
|
+
# @return [Symbol] mode of encryption/decryption
|
25
|
+
attr_reader :mode
|
26
|
+
# @return [Symbol] action to execute
|
27
|
+
attr_reader :action
|
28
|
+
# @return [Symbol] OpenSSL public key cipher type
|
29
|
+
attr_reader :asym_cipher_type
|
30
|
+
# @return [Symbol] alias of Izokatu exporter
|
31
|
+
attr_reader :exporter
|
32
|
+
# @return [Symbol] alias of Izokatu importer
|
33
|
+
attr_reader :importer
|
34
|
+
# @return [String] OpenSSL private key cipher
|
35
|
+
# @note also used for OpenSSL public key ec key generation
|
36
|
+
attr_reader :cipher
|
37
|
+
# @return [Hash] options from user merged with default
|
38
|
+
attr_reader :options
|
39
|
+
|
40
|
+
# Default options for Izokatu call
|
41
|
+
DEFAULT_OPTIONS = {
|
42
|
+
via: :rbnacl,
|
43
|
+
mode: :private_key,
|
44
|
+
action: :encryption,
|
45
|
+
asym_cipher_type: :ec,
|
46
|
+
exporter: :function,
|
47
|
+
importer: :function,
|
48
|
+
cipher: 'secp521r1',
|
49
|
+
encrypted_data_filename: 'encrypted_data',
|
50
|
+
decrypter_params_filename: 'decrypter_params',
|
51
|
+
delete_imported: false
|
52
|
+
}.freeze
|
53
|
+
|
54
|
+
# Map of exporters and their symbol aliases
|
55
|
+
EXPORTER_MAPPING = {
|
56
|
+
function: FunctionExporter,
|
57
|
+
file: FileExporter,
|
58
|
+
stdout: StdoutExporter
|
59
|
+
}.freeze
|
60
|
+
|
61
|
+
# Map of importers and their symbol aliases
|
62
|
+
IMPORTER_MAPPING = {
|
63
|
+
function: FunctionImporter,
|
64
|
+
file: FileImporter
|
65
|
+
}.freeze
|
66
|
+
|
67
|
+
Contract Contracts::HashOf[Symbol, Any] =>
|
68
|
+
Contracts::HashOf[Symbol, Any]
|
69
|
+
# Public method to work with
|
70
|
+
#
|
71
|
+
# @param options [Hash] options from user
|
72
|
+
#
|
73
|
+
# @return [Hash] Encrypted/decrypted data with params or public/private keys
|
74
|
+
#
|
75
|
+
# @since 0.1.0
|
76
|
+
# @api public
|
77
|
+
#
|
78
|
+
# @example RbNaCl private key cryptography
|
79
|
+
# encrypted_data = Izokatu.call(clear_data_string: 'Some data')
|
80
|
+
# Izokatu.call(action: :decryption, **encrypted_data)
|
81
|
+
# => {:decrypted_data_string=>"Some data"}
|
82
|
+
#
|
83
|
+
# @example RbNaCl public key cryptography
|
84
|
+
# keypair1 = Izokatu.call(action: :keys_generation, mode: :public_key)
|
85
|
+
# keypair2 = Izokatu.call(action: :keys_generation, mode: :public_key)
|
86
|
+
# encrypted_data = Izokatu.call(
|
87
|
+
# clear_data_string: 'Some data',
|
88
|
+
# mode: :public_key,
|
89
|
+
# public_key: keypair1[:public_key],
|
90
|
+
# private_key: keypair2[:private_key]
|
91
|
+
# )
|
92
|
+
# Izokatu.call(
|
93
|
+
# action: :decryption,
|
94
|
+
# mode: :public_key,
|
95
|
+
# **encrypted_data,
|
96
|
+
# public_key: keypair2[:public_key],
|
97
|
+
# private_key: keypair1[:private_key]
|
98
|
+
# )
|
99
|
+
# => {:decrypted_data_string=>"Some data"}
|
100
|
+
#
|
101
|
+
# @example OpenSSL private key cryptography
|
102
|
+
# encrypted_data = Izokatu.call(
|
103
|
+
# clear_data_string: 'Some data',
|
104
|
+
# via: :openssl,
|
105
|
+
# cipher: 'AES-256-GCM'
|
106
|
+
# )
|
107
|
+
# Izokatu.call(
|
108
|
+
# action: :decryption,
|
109
|
+
# **encrypted_data,
|
110
|
+
# via: :openssl,
|
111
|
+
# cipher: 'AES-256-GCM'
|
112
|
+
# )
|
113
|
+
# => {:decrypted_data_string=>"Some data"}
|
114
|
+
#
|
115
|
+
# @example OpenSSL EC public key cryptography
|
116
|
+
# keypair_options = {
|
117
|
+
# action: :keys_generation,
|
118
|
+
# mode: :public_key,
|
119
|
+
# via: :openssl
|
120
|
+
# }
|
121
|
+
# keypair1 = Izokatu.call(keypair_options)
|
122
|
+
# keypair2 = Izokatu.call(keypair_options)
|
123
|
+
# encrypted_data = Izokatu.call(
|
124
|
+
# clear_data_string: 'Some data',
|
125
|
+
# mode: :public_key,
|
126
|
+
# via: :openssl,
|
127
|
+
# public_key:
|
128
|
+
# keypair1[:public_key],
|
129
|
+
# private_key: keypair2[:private_key]
|
130
|
+
# )
|
131
|
+
# Izokatu.call(
|
132
|
+
# action: :decryption,
|
133
|
+
# mode: :public_key,
|
134
|
+
# via: :openssl,
|
135
|
+
# **encrypted_data,
|
136
|
+
# public_key: keypair2[:public_key],
|
137
|
+
# private_key: keypair1[:private_key]
|
138
|
+
# )
|
139
|
+
# => {:decrypted_data_string=>"Some data"}
|
140
|
+
#
|
141
|
+
# @example OpenSSL RSA public key cryptography
|
142
|
+
# keypair_options = {
|
143
|
+
# action: :keys_generation,
|
144
|
+
# mode: :public_key,
|
145
|
+
# via: :openssl,
|
146
|
+
# asym_cipher_type: :rsa,
|
147
|
+
# bit_number: 4096
|
148
|
+
# }
|
149
|
+
# keypair1 = Izokatu.call(keypair_options)
|
150
|
+
# keypair2 = Izokatu.call(keypair_options)
|
151
|
+
# encrypted_data = Izokatu.call(
|
152
|
+
# clear_data_string: 'Some data',
|
153
|
+
# mode: :public_key,
|
154
|
+
# via: :openssl,
|
155
|
+
# public_key: keypair1[:public_key],
|
156
|
+
# private_key: keypair2[:private_key],
|
157
|
+
# asym_cipher_type: :rsa
|
158
|
+
# )
|
159
|
+
# Izokatu.call(
|
160
|
+
# action: :decryption,
|
161
|
+
# mode: :public_key,
|
162
|
+
# via: :openssl,
|
163
|
+
# **encrypted_data,
|
164
|
+
# public_key: keypair2[:public_key],
|
165
|
+
# private_key: keypair1[:private_key],
|
166
|
+
# asym_cipher_type: :rsa
|
167
|
+
# )
|
168
|
+
# => {:decrypted_data_string=>"Some data"}
|
169
|
+
def call(**options)
|
170
|
+
initialize!(options)
|
171
|
+
perform
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
Contract Contracts::HashOf[Symbol, Any] => Any
|
177
|
+
# Initializing Izokatu variables
|
178
|
+
#
|
179
|
+
# @param options (#options)
|
180
|
+
#
|
181
|
+
# @since 0.1.0
|
182
|
+
def initialize!(options)
|
183
|
+
options = merge_options!(options)
|
184
|
+
@via = options[:via]
|
185
|
+
@mode = options[:mode]
|
186
|
+
@action = options[:action]
|
187
|
+
@asym_cipher_type = options[:asym_cipher_type]
|
188
|
+
@exporter = options[:exporter]
|
189
|
+
@importer = options[:importer]
|
190
|
+
@cipher = format_cipher(options[:cipher])
|
191
|
+
@options = options
|
192
|
+
end
|
193
|
+
|
194
|
+
Contract Contracts::HashOf[Symbol, Any] =>
|
195
|
+
Contracts::HashOf[Symbol, Any]
|
196
|
+
# Merging user option with default
|
197
|
+
#
|
198
|
+
# @param options [Hash] options from user
|
199
|
+
#
|
200
|
+
# @return [Hash] user options merged with default
|
201
|
+
#
|
202
|
+
# @since 0.1.0
|
203
|
+
def merge_options!(options)
|
204
|
+
options ? DEFAULT_OPTIONS.merge(options) : DEFAULT_OPTIONS
|
205
|
+
end
|
206
|
+
|
207
|
+
Contract String => String
|
208
|
+
# Formatting name of OpenSSL private key ciphers
|
209
|
+
#
|
210
|
+
# @param cipher [String] cipher name from user
|
211
|
+
#
|
212
|
+
# @return [String] formatted cipher name
|
213
|
+
#
|
214
|
+
# @since 0.1.0
|
215
|
+
def format_cipher(cipher)
|
216
|
+
Openssl::PKEY_CIPHERS.include?(cipher) ? cipher.upcase : cipher
|
217
|
+
end
|
218
|
+
|
219
|
+
Contract None => Contracts::HashOf[Symbol, Any]
|
220
|
+
# Verifying and processing merged options
|
221
|
+
#
|
222
|
+
# @return [Hash] Encrypted/decrypted data with params or public/private keys
|
223
|
+
#
|
224
|
+
# @since 0.1.0
|
225
|
+
def perform
|
226
|
+
verify_izokatu_options!
|
227
|
+
verify_exporter_class!
|
228
|
+
verify_importer_class!
|
229
|
+
verify_izokatu_cipher!
|
230
|
+
select_exporter_class!
|
231
|
+
select_importer_class!
|
232
|
+
process_izokatu_options!
|
233
|
+
end
|
234
|
+
|
235
|
+
# Verifying options value
|
236
|
+
#
|
237
|
+
# @raise [RuntimeError] if option value is unknown
|
238
|
+
#
|
239
|
+
# @since 0.1.0
|
240
|
+
def verify_izokatu_options!
|
241
|
+
raise 'ERROR: Unknown library!' unless %i[openssl rbnacl].include?(via)
|
242
|
+
raise 'ERROR: Unknown mode!' unless %i[private_key public_key].include?(mode)
|
243
|
+
raise 'ERROR: Unknown action!' unless %i[encryption decryption keys_generation].include?(action)
|
244
|
+
raise 'ERROR: Unknown asym_cipher_type!' unless %i[ec rsa].include?(asym_cipher_type)
|
245
|
+
end
|
246
|
+
|
247
|
+
# Verifying exporter alias
|
248
|
+
#
|
249
|
+
# @raise [RuntimeError] if exporter alias is unknown
|
250
|
+
#
|
251
|
+
# @since 0.1.0
|
252
|
+
def verify_exporter_class!
|
253
|
+
raise 'ERROR: Unknown exporter!' unless %i[stdout file function].include?(exporter)
|
254
|
+
end
|
255
|
+
|
256
|
+
# Verifying importer alias
|
257
|
+
#
|
258
|
+
# @raise [RuntimeError] if importer alias is unknown
|
259
|
+
#
|
260
|
+
# @since 0.1.0
|
261
|
+
def verify_importer_class!
|
262
|
+
raise 'ERROR: Unknown importer!' unless %i[file function].include?(importer)
|
263
|
+
end
|
264
|
+
|
265
|
+
# Verifying cipher
|
266
|
+
#
|
267
|
+
# @raise [RuntimeError] if cipher name is unknowm
|
268
|
+
#
|
269
|
+
# @note also raising exception if cipher is using unsupported WRAP mode
|
270
|
+
#
|
271
|
+
# @since 0.1.0
|
272
|
+
def verify_izokatu_cipher!
|
273
|
+
raise 'ERROR: Unknown cipher!' if unknown_cipher?
|
274
|
+
raise 'ERROR: Wrap ciphers are not supported!' if wrap_cipher?
|
275
|
+
end
|
276
|
+
|
277
|
+
Contract None => Bool
|
278
|
+
# Verifying cipher is not from OpenSSL private key ciphers or EC ciphers
|
279
|
+
#
|
280
|
+
# @return [Bool] result of verifying cipher is not from OpenSSL private key ciphers of EC ciphers
|
281
|
+
#
|
282
|
+
# @since 0.1.0
|
283
|
+
def unknown_cipher?
|
284
|
+
!Openssl::PKEY_CIPHERS.include?(cipher) && !Openssl::PBKEY_EC_CIPHERS.include?(cipher)
|
285
|
+
end
|
286
|
+
|
287
|
+
Contract None => Bool
|
288
|
+
# Verifying cipher is using WRAP mode
|
289
|
+
#
|
290
|
+
# @return [Bool] result of verifying cipher is using WRAP mode
|
291
|
+
#
|
292
|
+
# @since 0.1.0
|
293
|
+
def wrap_cipher?
|
294
|
+
cipher.include?('wrap') || cipher.include?('WRAP')
|
295
|
+
end
|
296
|
+
|
297
|
+
Contract None => Class
|
298
|
+
# Changing exporter options value from alias of exporter class to exporter class
|
299
|
+
#
|
300
|
+
# @return [Class] exporter class
|
301
|
+
#
|
302
|
+
# @since 0.1.0
|
303
|
+
def select_exporter_class!
|
304
|
+
options[:exporter] = EXPORTER_MAPPING[exporter]
|
305
|
+
@exporter = options[:exporter]
|
306
|
+
end
|
307
|
+
|
308
|
+
Contract None => Class
|
309
|
+
# Changing importer options value from alias of importer class to importer class
|
310
|
+
#
|
311
|
+
# @return [Class] importer class
|
312
|
+
#
|
313
|
+
# @since 0.1.0
|
314
|
+
def select_importer_class!
|
315
|
+
options[:importer] = IMPORTER_MAPPING[importer]
|
316
|
+
@importer = options[:importer]
|
317
|
+
end
|
318
|
+
|
319
|
+
Contract None => Contracts::HashOf[Symbol, Any]
|
320
|
+
# Importing encrypted data, selecting action class with options to call, exporting result of call
|
321
|
+
#
|
322
|
+
# @return [Hash] Encrypted/decrypted data with params or public/private keys
|
323
|
+
#
|
324
|
+
# @since 0.1.0
|
325
|
+
def process_izokatu_options!
|
326
|
+
import_encrypted!(options: options, decode: true) if action == :decryption
|
327
|
+
action_class = select_action
|
328
|
+
action_options = select_action_options(action_class)
|
329
|
+
data, params = action_class.call(**action_options)
|
330
|
+
izokatu_export(data: data, params: params, encode: true)
|
331
|
+
end
|
332
|
+
|
333
|
+
# Izokatu export function
|
334
|
+
#
|
335
|
+
# @param data [Hash] encrypted/decrypted data for export
|
336
|
+
# @param params [Hash] decrypter params for export
|
337
|
+
#
|
338
|
+
# @return [Hash] result of action class call
|
339
|
+
#
|
340
|
+
# @since 0.1.0
|
341
|
+
def izokatu_export(data:, params:, encode:)
|
342
|
+
# WTF: Somehow, even Contract Any => Any for this method is violated
|
343
|
+
case action
|
344
|
+
when :encryption
|
345
|
+
export_encrypted!(encrypted_data: data, decrypter_params: params || {}, encode: encode)
|
346
|
+
when :decryption
|
347
|
+
export_decrypted!(decrypted_data: data, encode: false)
|
348
|
+
else
|
349
|
+
data
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
Contract None => Class
|
354
|
+
# Selecting action class to be called, based on options
|
355
|
+
#
|
356
|
+
# @return [Class] action class
|
357
|
+
#
|
358
|
+
# @since 0.1.0
|
359
|
+
def select_action
|
360
|
+
ActionCallSelector.call(
|
361
|
+
via: via,
|
362
|
+
mode: mode,
|
363
|
+
action: action,
|
364
|
+
asym_cipher_type: asym_cipher_type,
|
365
|
+
ccm_cipher: ccm_cipher?,
|
366
|
+
auth_cipher: cipher_authenticated?
|
367
|
+
)
|
368
|
+
end
|
369
|
+
|
370
|
+
Contract Class => Contracts::HashOf[Symbol, Any]
|
371
|
+
# Selecting options for action class, based on action class
|
372
|
+
#
|
373
|
+
# @param action_class [Class] selected action class
|
374
|
+
#
|
375
|
+
# @return [Hash] options for action class
|
376
|
+
#
|
377
|
+
# @since 0.1.0
|
378
|
+
def select_action_options(action_class)
|
379
|
+
ActionCallOptionsSelector.call(action_class: action_class, options: options)
|
380
|
+
end
|
381
|
+
|
382
|
+
Contract None => Bool
|
383
|
+
# Verifying cipher mode is equal to CCM
|
384
|
+
#
|
385
|
+
# @return [Bool] result of verifying cipher mode is equal to CCM
|
386
|
+
#
|
387
|
+
# @since 0.1.0
|
388
|
+
def ccm_cipher?
|
389
|
+
cipher.include?('CCM')
|
390
|
+
end
|
391
|
+
|
392
|
+
Contract None => Bool
|
393
|
+
# Verifying cipher as authenticated.
|
394
|
+
# If cipher is authenticated, authenticated tag will be computed from encrypted data.
|
395
|
+
# @note passing EC ciphers as authenticated. Those ciphers used only for key generation
|
396
|
+
#
|
397
|
+
# @return [Bool] result of verifying cipher as authenticated
|
398
|
+
#
|
399
|
+
# @since 0.1.0
|
400
|
+
def cipher_authenticated?
|
401
|
+
return true if Openssl::PBKEY_EC_CIPHERS.include?(cipher)
|
402
|
+
|
403
|
+
OpenSSL::Cipher.new(cipher).encrypt.authenticated? && openssl_auth_exception?
|
404
|
+
end
|
405
|
+
|
406
|
+
Contract None => Bool
|
407
|
+
# Verifying cipher is not using CBC mode or equal to RC4-HMAC-MD5.
|
408
|
+
# These conditions specifying ciphers which passing authenticated? check from OpenSSL, but are not authenticated.
|
409
|
+
#
|
410
|
+
# @return [Bool] result of verifying cipher as OpenSSL exceptions from authenticated? check
|
411
|
+
#
|
412
|
+
# @since 0.1.0
|
413
|
+
def openssl_auth_exception?
|
414
|
+
# In tests of openssl gem, I don't saw assigment of auth_tag or auth_data for cbc ciphers, only padding
|
415
|
+
# (https://github.com/ruby/openssl/blob/master/test/openssl/test_cipher.rb)
|
416
|
+
# Get this error:
|
417
|
+
# OpenSSL::Cipher::CipherError: retrieving the authentication tag failed: ctrl operation not implemented
|
418
|
+
# If not assigning authentication tag, get this error:
|
419
|
+
# ':in `iv_len=': cipher does not support AEAD (OpenSSL::Cipher::CipherError)'
|
420
|
+
!cipher.include?('CBC') && cipher != 'RC4-HMAC-MD5'
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Izokatu
|
4
|
+
# Izokatu selector of options for selected action class
|
5
|
+
class ActionCallOptionsSelector
|
6
|
+
extend Callable
|
7
|
+
|
8
|
+
include Contracts
|
9
|
+
|
10
|
+
# @return [Class] selected action class
|
11
|
+
attr_reader :action_class
|
12
|
+
# @return [Symbol] action to execute
|
13
|
+
attr_reader :action
|
14
|
+
# @return [Symbol] library used for encryption/decryption
|
15
|
+
attr_reader :via
|
16
|
+
# @return [String] OpenSSL private key cipher
|
17
|
+
# @note also used for OpenSSL public key ec key generation
|
18
|
+
attr_reader :cipher
|
19
|
+
# @return [String] string of clear data for encryption
|
20
|
+
attr_reader :clear_data_string
|
21
|
+
# @return [String] string of encrypted data for decryption
|
22
|
+
attr_reader :encrypted_data_string
|
23
|
+
# @return [RBNACL_KEY_CLASSES || OPENSSL_KEY_CLASSES] public key for public key encryption/decryption
|
24
|
+
attr_reader :public_key
|
25
|
+
# @return [RBNACL_KEY_CLASSES || OPENSSL_KEY_CLASSES] private key for public key encryption/decryption
|
26
|
+
attr_reader :private_key
|
27
|
+
# @return [String] encryption key for private key encryption/decryption
|
28
|
+
attr_reader :key
|
29
|
+
# @return [String] initialization vector for one-time use
|
30
|
+
attr_reader :nonce
|
31
|
+
# @return [String] authenticated data
|
32
|
+
attr_reader :auth_data
|
33
|
+
# @return [String] authentication tag
|
34
|
+
attr_reader :auth_tag
|
35
|
+
# @return [Hash] options for OpenSSL public key EC encryption/decryption
|
36
|
+
attr_reader :ecies_options
|
37
|
+
# @return [Integer] bit number for OpenSSL public key RSA encryption/decryption
|
38
|
+
attr_reader :bit_number
|
39
|
+
|
40
|
+
# RbNaCl public key classes, used for contracts
|
41
|
+
RBNACL_KEY_CLASSES = [
|
42
|
+
RbNaCl::Boxes::Curve25519XSalsa20Poly1305::PrivateKey,
|
43
|
+
RbNaCl::Boxes::Curve25519XSalsa20Poly1305::PublicKey
|
44
|
+
].freeze
|
45
|
+
|
46
|
+
# OpenSSL public key classes, used for contracts
|
47
|
+
OPENSSL_KEY_CLASSES = [
|
48
|
+
OpenSSL::PKey::RSA,
|
49
|
+
OpenSSL::PKey::EC
|
50
|
+
].freeze
|
51
|
+
|
52
|
+
Contract Contracts::HashOf[Symbol, Or[Class, Contracts::HashOf[Symbol, Any]]] => Any
|
53
|
+
# Initializing options for action class
|
54
|
+
#
|
55
|
+
# @param action_class (#action_class)
|
56
|
+
# @param options (#options)
|
57
|
+
#
|
58
|
+
# @since 0.1.0
|
59
|
+
def initialize(action_class:, options:)
|
60
|
+
@action_class = action_class.to_s
|
61
|
+
@action = options[:action]
|
62
|
+
@via = options[:via]
|
63
|
+
@cipher = options[:cipher]
|
64
|
+
@clear_data_string = options[:clear_data_string]
|
65
|
+
@encrypted_data_string = options[:encrypted_data_string]
|
66
|
+
@public_key = options[:public_key]
|
67
|
+
@private_key = options[:private_key]
|
68
|
+
@key = options[:key]
|
69
|
+
@nonce = options[:nonce]
|
70
|
+
@auth_data = options[:auth_data]
|
71
|
+
@auth_tag = options[:auth_tag]
|
72
|
+
@ecies_options = options[:ecies_options]
|
73
|
+
@bit_number = options[:bit_number]
|
74
|
+
end
|
75
|
+
|
76
|
+
Contract None => Contracts::HashOf[Symbol, Any]
|
77
|
+
# Selecting options for keys generation class or for encryption/decryption class
|
78
|
+
#
|
79
|
+
# @return [Hash] options for action class call
|
80
|
+
#
|
81
|
+
# @since 0.1.0
|
82
|
+
def perform
|
83
|
+
action == :keys_generation ? select_keys_generation_action_options : select_default_action_options
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
Contract None => Or[{}, Contracts::HashOf[Symbol, Or[String, Pos]]]
|
89
|
+
# Selecting options for keys generation class
|
90
|
+
#
|
91
|
+
# @return [Hash] options for keys generation class
|
92
|
+
#
|
93
|
+
# @since 0.1.0
|
94
|
+
def select_keys_generation_action_options
|
95
|
+
case action_class
|
96
|
+
when 'Izokatu::Rbnacl::PublicKey::KeysGenerator'
|
97
|
+
{}
|
98
|
+
when 'Izokatu::Openssl::PublicKey::RSA::KeysGenerator'
|
99
|
+
{ bit_number: bit_number }
|
100
|
+
when 'Izokatu::Openssl::PublicKey::EC::KeysGenerator'
|
101
|
+
{ cipher: cipher }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
Contract None => Contracts::HashOf[Symbol, Or[*RBNACL_KEY_CLASSES, *OPENSSL_KEY_CLASSES, String, nil]]
|
106
|
+
# Selecting options for encryption/decryption class
|
107
|
+
#
|
108
|
+
# @return [Hash] options for encryption/decryption class
|
109
|
+
#
|
110
|
+
# @since 0.1.0
|
111
|
+
def select_default_action_options
|
112
|
+
via == :rbnacl ? select_rbnacl_action_options : select_openssl_action_options
|
113
|
+
end
|
114
|
+
|
115
|
+
Contract None => Contracts::HashOf[Symbol, Or[*RBNACL_KEY_CLASSES, String, nil]]
|
116
|
+
# Selecting options for Rbnacl encryption/decryption class
|
117
|
+
#
|
118
|
+
# @return [Hash] options for Rbnacl encryption/decryption class
|
119
|
+
#
|
120
|
+
# @since 0.1.0
|
121
|
+
def select_rbnacl_action_options
|
122
|
+
case action_class
|
123
|
+
when 'Izokatu::Rbnacl::PrivateKey::Encrypter'
|
124
|
+
{ auth_data: auth_data, clear_data: clear_data_string }
|
125
|
+
when 'Izokatu::Rbnacl::PrivateKey::Decrypter'
|
126
|
+
{
|
127
|
+
encrypted_data: encrypted_data_string,
|
128
|
+
nonce: nonce,
|
129
|
+
key: key,
|
130
|
+
auth_data: auth_data
|
131
|
+
}
|
132
|
+
when 'Izokatu::Rbnacl::PublicKey::Encrypter'
|
133
|
+
{
|
134
|
+
public_key: public_key,
|
135
|
+
private_key: private_key,
|
136
|
+
clear_data: clear_data_string
|
137
|
+
}
|
138
|
+
when 'Izokatu::Rbnacl::PublicKey::Decrypter'
|
139
|
+
{
|
140
|
+
encrypted_data: encrypted_data_string,
|
141
|
+
nonce: nonce,
|
142
|
+
public_key: public_key,
|
143
|
+
private_key: private_key
|
144
|
+
}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
Contract None => Contracts::HashOf[Symbol, Or[*OPENSSL_KEY_CLASSES, String, nil]]
|
149
|
+
# Selecting options for Openssl encryption/decryption class
|
150
|
+
#
|
151
|
+
# @return [Hash] options for Openssl encryption/decryption class
|
152
|
+
#
|
153
|
+
# @since 0.1.0
|
154
|
+
def select_openssl_action_options
|
155
|
+
case action_class
|
156
|
+
when 'Izokatu::Openssl::PrivateKey::Default::Encrypter'
|
157
|
+
{ cipher: cipher, clear_data: clear_data_string }
|
158
|
+
when 'Izokatu::Openssl::PrivateKey::Default::Decrypter'
|
159
|
+
{
|
160
|
+
cipher: cipher,
|
161
|
+
encrypted_data: encrypted_data_string,
|
162
|
+
key: key,
|
163
|
+
nonce: nonce
|
164
|
+
}
|
165
|
+
when 'Izokatu::Openssl::PrivateKey::Auth::Encrypter'
|
166
|
+
{
|
167
|
+
cipher: cipher,
|
168
|
+
clear_data: clear_data_string,
|
169
|
+
auth_data: auth_data
|
170
|
+
}
|
171
|
+
when 'Izokatu::Openssl::PrivateKey::Auth::Decrypter'
|
172
|
+
{
|
173
|
+
cipher: cipher,
|
174
|
+
encrypted_data: encrypted_data_string,
|
175
|
+
key: key,
|
176
|
+
nonce: nonce,
|
177
|
+
auth_data: auth_data,
|
178
|
+
auth_tag: auth_tag
|
179
|
+
}
|
180
|
+
when 'Izokatu::Openssl::PrivateKey::Auth::CCM::Encrypter'
|
181
|
+
{
|
182
|
+
cipher: cipher,
|
183
|
+
clear_data: clear_data_string,
|
184
|
+
auth_data: auth_data
|
185
|
+
}
|
186
|
+
when 'Izokatu::Openssl::PrivateKey::Auth::CCM::Decrypter'
|
187
|
+
{
|
188
|
+
cipher: cipher,
|
189
|
+
encrypted_data: encrypted_data_string,
|
190
|
+
key: key,
|
191
|
+
nonce: nonce,
|
192
|
+
auth_data: auth_data,
|
193
|
+
auth_tag: auth_tag
|
194
|
+
}
|
195
|
+
when 'Izokatu::Openssl::PublicKey::RSA::Encrypter'
|
196
|
+
{ clear_data: clear_data_string, public_key: public_key }
|
197
|
+
when 'Izokatu::Openssl::PublicKey::RSA::Decrypter'
|
198
|
+
{ private_key: private_key, encrypted_data: encrypted_data_string }
|
199
|
+
when 'Izokatu::Openssl::PublicKey::EC::Encrypter'
|
200
|
+
{
|
201
|
+
clear_data: clear_data_string,
|
202
|
+
public_key: public_key,
|
203
|
+
ecies_options: ecies_options
|
204
|
+
}
|
205
|
+
when 'Izokatu::Openssl::PublicKey::EC::Decrypter'
|
206
|
+
{
|
207
|
+
private_key: private_key,
|
208
|
+
encrypted_data: encrypted_data_string,
|
209
|
+
ecies_options: ecies_options
|
210
|
+
}
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|