module Izokatu
Main module to work with.
Constants
- DEFAULT_OPTIONS
Default options for
Izokatu
call- EXPORTER_MAPPING
Map of exporters and their symbol aliases
- IMPORTER_MAPPING
Map of importers and their symbol aliases
- VERSION
Gem version
Attributes
@return [Symbol] action to execute
@return [Symbol] OpenSSL public key cipher type
@return [String] OpenSSL private key cipher @note also used for OpenSSL public key ec key generation
@return [Symbol] alias of Izokatu
exporter
@return [Symbol] alias of Izokatu
importer
@return [Symbol] mode of encryption/decryption
@return [Hash] options from user merged with default
@return [Symbol] library used for encryption/decryption
Public Class Methods
Public method to work with
@param options [Hash] options from user
@return [Hash] Encrypted/decrypted data with params or public/private keys
@since 0.1.0 @api public
@example RbNaCl private key cryptography
encrypted_data = Izokatu.call(clear_data_string: 'Some data') Izokatu.call(action: :decryption, **encrypted_data) => {:decrypted_data_string=>"Some data"}
@example 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"}
@example 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"}
@example 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"}
@example 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"}
# File lib/izokatu.rb, line 171 def call(**options) initialize!(options) perform end
Private Class Methods
Verifying cipher mode is equal to CCM
@return [Bool] result of verifying cipher mode is equal to CCM
@since 0.1.0
# File lib/izokatu.rb, line 390 def ccm_cipher? cipher.include?('CCM') end
Verifying cipher as authenticated. If cipher is authenticated, authenticated tag will be computed from encrypted data. @note passing EC ciphers as authenticated. Those ciphers used only for key generation
@return [Bool] result of verifying cipher as authenticated
@since 0.1.0
# 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
Formatting name of OpenSSL private key ciphers
@param cipher [String] cipher name from user
@return [String] formatted cipher name
@since 0.1.0
# File lib/izokatu.rb, line 217 def format_cipher(cipher) Openssl::PKEY_CIPHERS.include?(cipher) ? cipher.upcase : cipher end
Initializing Izokatu
variables
@param options (options)
@since 0.1.0
# 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 function
@param data [Hash] encrypted/decrypted data for export @param params [Hash] decrypter params for export
@return [Hash] result of action class call
@since 0.1.0
# 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
Merging user option with default
@param options [Hash] options from user
@return [Hash] user options merged with default
@since 0.1.0
# File lib/izokatu.rb, line 205 def merge_options!(options) options ? DEFAULT_OPTIONS.merge(options) : DEFAULT_OPTIONS end
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.
@return [Bool] result of verifying cipher as OpenSSL exceptions from authenticated? check
@since 0.1.0
# 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
Verifying and processing merged options
@return [Hash] Encrypted/decrypted data with params or public/private keys
@since 0.1.0
# 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
Importing encrypted data, selecting action class with options to call, exporting result of call
@return [Hash] Encrypted/decrypted data with params or public/private keys
@since 0.1.0
# 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
Selecting action class to be called, based on options
@return [Class] action class
@since 0.1.0
# 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
Selecting options for action class, based on action class
@param action_class [Class] selected action class
@return [Hash] options for action class
@since 0.1.0
# File lib/izokatu.rb, line 380 def select_action_options(action_class) ActionCallOptionsSelector.call(action_class: action_class, options: options) end
Changing exporter options value from alias of exporter class to exporter class
@return [Class] exporter class
@since 0.1.0
# File lib/izokatu.rb, line 305 def select_exporter_class! options[:exporter] = EXPORTER_MAPPING[exporter] @exporter = options[:exporter] end
Changing importer options value from alias of importer class to importer class
@return [Class] importer class
@since 0.1.0
# File lib/izokatu.rb, line 316 def select_importer_class! options[:importer] = IMPORTER_MAPPING[importer] @importer = options[:importer] end
Verifying cipher is not from OpenSSL private key ciphers or EC ciphers
@return [Bool] result of verifying cipher is not from OpenSSL private key ciphers of EC ciphers
@since 0.1.0
# File lib/izokatu.rb, line 285 def unknown_cipher? !Openssl::PKEY_CIPHERS.include?(cipher) && !Openssl::PBKEY_EC_CIPHERS.include?(cipher) end
Verifying exporter alias
@raise [RuntimeError] if exporter alias is unknown
@since 0.1.0
# File lib/izokatu.rb, line 254 def verify_exporter_class! raise 'ERROR: Unknown exporter!' unless %i[stdout file function].include?(exporter) end
Verifying importer alias
@raise [RuntimeError] if importer alias is unknown
@since 0.1.0
# File lib/izokatu.rb, line 263 def verify_importer_class! raise 'ERROR: Unknown importer!' unless %i[file function].include?(importer) end
Verifying cipher
@raise [RuntimeError] if cipher name is unknowm
@note also raising exception if cipher is using unsupported WRAP mode
@since 0.1.0
# 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
Verifying options value
@raise [RuntimeError] if option value is unknown
@since 0.1.0
# 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
Verifying cipher is using WRAP mode
@return [Bool] result of verifying cipher is using WRAP mode
@since 0.1.0
# File lib/izokatu.rb, line 295 def wrap_cipher? cipher.include?('wrap') || cipher.include?('WRAP') end