Module: Izokatu

Extended by:
Helpers
Includes:
Contracts
Defined in:
lib/izokatu.rb,
lib/izokatu/ciphers.rb,
lib/izokatu/helpers.rb,
lib/izokatu/version.rb,
lib/izokatu/callable.rb,
lib/izokatu/exporter.rb,
lib/izokatu/decrypter.rb,
lib/izokatu/encrypter.rb,
lib/izokatu/keys_generator.rb,
lib/izokatu/rbnacl/decrypter.rb,
lib/izokatu/rbnacl/encrypter.rb,
lib/izokatu/action_call_selector.rb,
lib/izokatu/exporter/file_exporter.rb,
lib/izokatu/importer/file_importer.rb,
lib/izokatu/exporter/stdout_exporter.rb,
lib/izokatu/exporter/function_exporter.rb,
lib/izokatu/importer/function_importer.rb,
lib/izokatu/rbnacl/public_key/decrypter.rb,
lib/izokatu/rbnacl/public_key/encrypter.rb,
lib/izokatu/action_call_options_selector.rb,
lib/izokatu/rbnacl/private_key/decrypter.rb,
lib/izokatu/rbnacl/private_key/encrypter.rb,
lib/izokatu/openssl/public_key/ec/decrypter.rb,
lib/izokatu/openssl/public_key/ec/encrypter.rb,
lib/izokatu/openssl/public_key/rsa/decrypter.rb,
lib/izokatu/openssl/public_key/rsa/encrypter.rb,
lib/izokatu/rbnacl/public_key/keys_generator.rb,
lib/izokatu/openssl/private_key/auth/decrypter.rb,
lib/izokatu/openssl/private_key/auth/encrypter.rb,
lib/izokatu/openssl/public_key/ec/keys_generator.rb,
lib/izokatu/openssl/private_key/default/decrypter.rb,
lib/izokatu/openssl/private_key/default/encrypter.rb,
lib/izokatu/openssl/public_key/rsa/keys_generator.rb,
lib/izokatu/openssl/private_key/auth/ccm/decrypter.rb,
lib/izokatu/openssl/private_key/auth/ccm/encrypter.rb

Overview

Main module to work with.

Defined Under Namespace

Modules: Callable, Helpers, Openssl, Rbnacl Classes: ActionCallOptionsSelector, ActionCallSelector, Decrypter, Encrypter, Exporter, FileExporter, FileImporter, FunctionExporter, FunctionImporter, KeysGenerator, StdoutExporter

Constant Summary collapse

DEFAULT_OPTIONS =

Default options for Izokatu call

{
  via: :rbnacl,
  mode: :private_key,
  action: :encryption,
  asym_cipher_type: :ec,
  exporter: :function,
  importer: :function,
  cipher: 'secp521r1',
  encrypted_data_filename: 'encrypted_data',
  decrypter_params_filename: 'decrypter_params',
  delete_imported: false
}.freeze
EXPORTER_MAPPING =

Map of exporters and their symbol aliases

{
  function: FunctionExporter,
  file: FileExporter,
  stdout: StdoutExporter
}.freeze
IMPORTER_MAPPING =

Map of importers and their symbol aliases

{
  function: FunctionImporter,
  file: FileImporter
}.freeze
VERSION =

Gem version

'0.1.2'

Constants included from Helpers

Helpers::EC_CIPHER, Helpers::KEY_SYMBOL, Helpers::RBNACL_KEY_CLASSES

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from Helpers

decode_data, encode_data, export_data, export_decrypted!, export_encrypted!, generate_ec_keypair, generate_rbnacl_keypair, generate_rsa_keypair, import_data, import_encrypted!, import_encrypted_in_options!

Class Attribute Details

.actionSymbol (readonly)

Returns action to execute.

Returns:

  • (Symbol)

    action to execute



29
30
31
# File 'lib/izokatu.rb', line 29

def action
  @action
end

.asym_cipher_typeSymbol (readonly)

Returns OpenSSL public key cipher type.

Returns:

  • (Symbol)

    OpenSSL public key cipher type



31
32
33
# File 'lib/izokatu.rb', line 31

def asym_cipher_type
  @asym_cipher_type
end

.cipherString (readonly)

Note:

also used for OpenSSL public key ec key generation

Returns OpenSSL private key cipher.

Returns:

  • (String)

    OpenSSL private key cipher



38
39
40
# File 'lib/izokatu.rb', line 38

def cipher
  @cipher
end

.exporterSymbol (readonly)

Returns alias of Izokatu exporter.

Returns:

  • (Symbol)

    alias of Izokatu exporter



33
34
35
# File 'lib/izokatu.rb', line 33

def exporter
  @exporter
end

.importerSymbol (readonly)

Returns alias of Izokatu importer.

Returns:

  • (Symbol)

    alias of Izokatu importer



35
36
37
# File 'lib/izokatu.rb', line 35

def importer
  @importer
end

.modeSymbol (readonly)

Returns mode of encryption/decryption.

Returns:

  • (Symbol)

    mode of encryption/decryption



27
28
29
# File 'lib/izokatu.rb', line 27

def mode
  @mode
end

.optionsHash (readonly)

Returns options from user merged with default.

Returns:

  • (Hash)

    options from user merged with default



40
41
42
# File 'lib/izokatu.rb', line 40

def options
  @options
end

.viaSymbol (readonly)

Returns library used for encryption/decryption.

Returns:

  • (Symbol)

    library used for encryption/decryption



25
26
27
# File 'lib/izokatu.rb', line 25

def via
  @via
end

Class Method Details

.call(**options) ⇒ Hash

Public method to work with

Examples:

RbNaCl private key cryptography

encrypted_data = Izokatu.call(clear_data_string: 'Some data')
Izokatu.call(action: :decryption, **encrypted_data)
=> {:decrypted_data_string=>"Some data"}

RbNaCl public key cryptography

keypair1 = Izokatu.call(action: :keys_generation, mode: :public_key)
keypair2 = Izokatu.call(action: :keys_generation, mode: :public_key)
encrypted_data = Izokatu.call(
  clear_data_string: 'Some data',
  mode: :public_key,
  public_key: keypair1[:public_key],
  private_key: keypair2[:private_key]
)
Izokatu.call(
  action: :decryption,
  mode: :public_key,
  **encrypted_data,
  public_key: keypair2[:public_key],
  private_key: keypair1[:private_key]
)
=> {:decrypted_data_string=>"Some data"}

OpenSSL private key cryptography

encrypted_data = Izokatu.call(
  clear_data_string: 'Some data',
  via: :openssl,
  cipher: 'AES-256-GCM'
)
Izokatu.call(
  action: :decryption,
  **encrypted_data,
  via: :openssl,
  cipher: 'AES-256-GCM'
)
=> {:decrypted_data_string=>"Some data"}

OpenSSL EC public key cryptography

keypair_options = {
  action: :keys_generation,
  mode: :public_key,
  via: :openssl
}
keypair1 = Izokatu.call(keypair_options)
keypair2 = Izokatu.call(keypair_options)
encrypted_data = Izokatu.call(
  clear_data_string: 'Some data',
  mode: :public_key,
  via: :openssl,
  public_key:
  keypair1[:public_key],
  private_key: keypair2[:private_key]
)
Izokatu.call(
  action: :decryption,
  mode: :public_key,
  via: :openssl,
  **encrypted_data,
  public_key: keypair2[:public_key],
  private_key: keypair1[:private_key]
)
=> {:decrypted_data_string=>"Some data"}

OpenSSL RSA public key cryptography

keypair_options = {
  action: :keys_generation,
  mode: :public_key,
  via: :openssl,
  asym_cipher_type: :rsa,
  bit_number: 4096
}
keypair1 = Izokatu.call(keypair_options)
keypair2 = Izokatu.call(keypair_options)
encrypted_data = Izokatu.call(
  clear_data_string: 'Some data',
  mode: :public_key,
  via: :openssl,
  public_key: keypair1[:public_key],
  private_key: keypair2[:private_key],
  asym_cipher_type: :rsa
)
Izokatu.call(
  action: :decryption,
  mode: :public_key,
  via: :openssl,
  **encrypted_data,
  public_key: keypair2[:public_key],
  private_key: keypair1[:private_key],
  asym_cipher_type: :rsa
)
=> {:decrypted_data_string=>"Some data"}

Parameters:

  • options (Hash)

    options from user

Returns:

  • (Hash)

    Encrypted/decrypted data with params or public/private keys

Since:

  • 0.1.0



171
172
173
174
# File 'lib/izokatu.rb', line 171

def call(**options)
  initialize!(options)
  perform
end

.ccm_cipher?Bool (private)

Verifying cipher mode is equal to CCM

Returns:

  • (Bool)

    result of verifying cipher mode is equal to CCM

Since:

  • 0.1.0



390
391
392
# File 'lib/izokatu.rb', line 390

def ccm_cipher?
  cipher.include?('CCM')
end

.cipher_authenticated?Bool (private)

Note:

passing EC ciphers as authenticated. Those ciphers used only for key generation

Verifying cipher as authenticated. If cipher is authenticated, authenticated tag will be computed from encrypted data.

Returns:

  • (Bool)

    result of verifying cipher as authenticated

Since:

  • 0.1.0



402
403
404
405
406
# File 'lib/izokatu.rb', line 402

def cipher_authenticated?
  return true if Openssl::PBKEY_EC_CIPHERS.include?(cipher)

  OpenSSL::Cipher.new(cipher).encrypt.authenticated? && openssl_auth_exception?
end

.format_cipher(cipher) ⇒ String (private)

Formatting name of OpenSSL private key ciphers

Parameters:

  • cipher (String)

    cipher name from user

Returns:

  • (String)

    formatted cipher name

Since:

  • 0.1.0



217
218
219
# File 'lib/izokatu.rb', line 217

def format_cipher(cipher)
  Openssl::PKEY_CIPHERS.include?(cipher) ? cipher.upcase : cipher
end

.initialize!(options) ⇒ Object (private)

Initializing Izokatu variables

Parameters:

Since:

  • 0.1.0



184
185
186
187
188
189
190
191
192
193
194
# File 'lib/izokatu.rb', line 184

def initialize!(options)
  options = merge_options!(options)
  @via = options[:via]
  @mode = options[:mode]
  @action = options[:action]
  @asym_cipher_type = options[:asym_cipher_type]
  @exporter = options[:exporter]
  @importer = options[:importer]
  @cipher = format_cipher(options[:cipher])
  @options = options
end

.izokatu_export(data:, params:, encode:) ⇒ Hash (private)

Izokatu export function

Parameters:

  • data (Hash)

    encrypted/decrypted data for export

  • params (Hash)

    decrypter params for export

Returns:

  • (Hash)

    result of action class call

Since:

  • 0.1.0



343
344
345
346
347
348
349
350
351
352
353
# File 'lib/izokatu.rb', line 343

def izokatu_export(data:, params:, encode:)
  # WTF: Somehow, even Contract Any => Any for this method is violated
  case action
  when :encryption
    export_encrypted!(encrypted_data: data, decrypter_params: params || {}, encode: encode)
  when :decryption
    export_decrypted!(decrypted_data: data, encode: false)
  else
    data
  end
end

.merge_options!(options) ⇒ Hash (private)

Merging user option with default

Parameters:

  • options (Hash)

    options from user

Returns:

  • (Hash)

    user options merged with default

Since:

  • 0.1.0



205
206
207
# File 'lib/izokatu.rb', line 205

def merge_options!(options)
  options ? DEFAULT_OPTIONS.merge(options) : DEFAULT_OPTIONS
end

.openssl_auth_exception?Bool (private)

Verifying cipher is not using CBC mode or equal to RC4-HMAC-MD5. These conditions specifying ciphers which passing authenticated? check from OpenSSL, but are not authenticated.

Returns:

  • (Bool)

    result of verifying cipher as OpenSSL exceptions from authenticated? check

Since:

  • 0.1.0



415
416
417
418
419
420
421
422
423
# File 'lib/izokatu.rb', line 415

def openssl_auth_exception?
  # In tests of openssl gem, I don't saw assigment of auth_tag or auth_data for cbc ciphers, only padding
  # (https://github.com/ruby/openssl/blob/master/test/openssl/test_cipher.rb)
  # Get this error:
  # OpenSSL::Cipher::CipherError: retrieving the authentication tag failed: ctrl operation not implemented
  # If not assigning authentication tag, get this error:
  # ':in `iv_len=': cipher does not support AEAD (OpenSSL::Cipher::CipherError)'
  !cipher.include?('CBC') && cipher != 'RC4-HMAC-MD5'
end

.performHash (private)

Verifying and processing merged options

Returns:

  • (Hash)

    Encrypted/decrypted data with params or public/private keys

Since:

  • 0.1.0



227
228
229
230
231
232
233
234
235
# File 'lib/izokatu.rb', line 227

def perform
  verify_izokatu_options!
  verify_exporter_class!
  verify_importer_class!
  verify_izokatu_cipher!
  select_exporter_class!
  select_importer_class!
  process_izokatu_options!
end

.process_izokatu_options!Hash (private)

Importing encrypted data, selecting action class with options to call, exporting result of call

Returns:

  • (Hash)

    Encrypted/decrypted data with params or public/private keys

Since:

  • 0.1.0



327
328
329
330
331
332
333
# File 'lib/izokatu.rb', line 327

def process_izokatu_options!
  import_encrypted!(options: options, decode: true) if action == :decryption
  action_class = select_action
  action_options = select_action_options(action_class)
  data, params = action_class.call(**action_options)
  izokatu_export(data: data, params: params, encode: true)
end

.select_actionClass (private)

Selecting action class to be called, based on options

Returns:

  • (Class)

    action class

Since:

  • 0.1.0



361
362
363
364
365
366
367
368
369
370
# File 'lib/izokatu.rb', line 361

def select_action
  ActionCallSelector.call(
    via: via,
    mode: mode,
    action: action,
    asym_cipher_type: asym_cipher_type,
    ccm_cipher: ccm_cipher?,
    auth_cipher: cipher_authenticated?
  )
end

.select_action_options(action_class) ⇒ Hash (private)

Selecting options for action class, based on action class

Parameters:

  • action_class (Class)

    selected action class

Returns:

  • (Hash)

    options for action class

Since:

  • 0.1.0



380
381
382
# File 'lib/izokatu.rb', line 380

def select_action_options(action_class)
  ActionCallOptionsSelector.call(action_class: action_class, options: options)
end

.select_exporter_class!Class (private)

Changing exporter options value from alias of exporter class to exporter class

Returns:

  • (Class)

    exporter class

Since:

  • 0.1.0



305
306
307
308
# File 'lib/izokatu.rb', line 305

def select_exporter_class!
  options[:exporter] = EXPORTER_MAPPING[exporter]
  @exporter = options[:exporter]
end

.select_importer_class!Class (private)

Changing importer options value from alias of importer class to importer class

Returns:

  • (Class)

    importer class

Since:

  • 0.1.0



316
317
318
319
# File 'lib/izokatu.rb', line 316

def select_importer_class!
  options[:importer] = IMPORTER_MAPPING[importer]
  @importer = options[:importer]
end

.unknown_cipher?Bool (private)

Verifying cipher is not from OpenSSL private key ciphers or EC ciphers

Returns:

  • (Bool)

    result of verifying cipher is not from OpenSSL private key ciphers of EC ciphers

Since:

  • 0.1.0



285
286
287
# File 'lib/izokatu.rb', line 285

def unknown_cipher?
  !Openssl::PKEY_CIPHERS.include?(cipher) && !Openssl::PBKEY_EC_CIPHERS.include?(cipher)
end

.verify_exporter_class!Object (private)

Verifying exporter alias

Raises:

  • (RuntimeError)

    if exporter alias is unknown

Since:

  • 0.1.0



254
255
256
# File 'lib/izokatu.rb', line 254

def verify_exporter_class!
  raise 'ERROR: Unknown exporter!' unless %i[stdout file function].include?(exporter)
end

.verify_importer_class!Object (private)

Verifying importer alias

Raises:

  • (RuntimeError)

    if importer alias is unknown

Since:

  • 0.1.0



263
264
265
# File 'lib/izokatu.rb', line 263

def verify_importer_class!
  raise 'ERROR: Unknown importer!' unless %i[file function].include?(importer)
end

.verify_izokatu_cipher!Object (private)

Note:

also raising exception if cipher is using unsupported WRAP mode

Verifying cipher

Raises:

  • (RuntimeError)

    if cipher name is unknowm

Since:

  • 0.1.0



274
275
276
277
# File 'lib/izokatu.rb', line 274

def verify_izokatu_cipher!
  raise 'ERROR: Unknown cipher!' if unknown_cipher?
  raise 'ERROR: Wrap ciphers are not supported!' if wrap_cipher?
end

.verify_izokatu_options!Object (private)

Verifying options value

Raises:

  • (RuntimeError)

    if option value is unknown

Since:

  • 0.1.0



242
243
244
245
246
247
# File 'lib/izokatu.rb', line 242

def verify_izokatu_options!
  raise 'ERROR: Unknown library!' unless %i[openssl rbnacl].include?(via)
  raise 'ERROR: Unknown mode!' unless %i[private_key public_key].include?(mode)
  raise 'ERROR: Unknown action!' unless %i[encryption decryption keys_generation].include?(action)
  raise 'ERROR: Unknown asym_cipher_type!' unless %i[ec rsa].include?(asym_cipher_type)
end

.wrap_cipher?Bool (private)

Verifying cipher is using WRAP mode

Returns:

  • (Bool)

    result of verifying cipher is using WRAP mode

Since:

  • 0.1.0



295
296
297
# File 'lib/izokatu.rb', line 295

def wrap_cipher?
  cipher.include?('wrap') || cipher.include?('WRAP')
end