symmetric-encryption 4.0.0 → 4.0.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.
Files changed (42) hide show
  1. checksums.yaml +5 -5
  2. data/Rakefile +2 -2
  3. data/bin/symmetric-encryption +1 -1
  4. data/lib/symmetric-encryption.rb +1 -1
  5. data/lib/symmetric_encryption.rb +2 -2
  6. data/lib/symmetric_encryption/cipher.rb +15 -18
  7. data/lib/symmetric_encryption/cli.rb +30 -36
  8. data/lib/symmetric_encryption/coerce.rb +3 -4
  9. data/lib/symmetric_encryption/config.rb +30 -34
  10. data/lib/symmetric_encryption/encoder.rb +0 -1
  11. data/lib/symmetric_encryption/exception.rb +0 -2
  12. data/lib/symmetric_encryption/extensions/active_record/base.rb +5 -2
  13. data/lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb +3 -5
  14. data/lib/symmetric_encryption/extensions/mongoid/encrypted.rb +0 -2
  15. data/lib/symmetric_encryption/generator.rb +3 -3
  16. data/lib/symmetric_encryption/header.rb +9 -4
  17. data/lib/symmetric_encryption/key.rb +3 -4
  18. data/lib/symmetric_encryption/keystore.rb +9 -9
  19. data/lib/symmetric_encryption/keystore/environment.rb +6 -7
  20. data/lib/symmetric_encryption/keystore/file.rb +5 -6
  21. data/lib/symmetric_encryption/keystore/memory.rb +2 -2
  22. data/lib/symmetric_encryption/railtie.rb +4 -7
  23. data/lib/symmetric_encryption/railties/symmetric_encryption_validator.rb +2 -1
  24. data/lib/symmetric_encryption/reader.rb +28 -39
  25. data/lib/symmetric_encryption/symmetric_encryption.rb +10 -8
  26. data/lib/symmetric_encryption/utils/re_encrypt_files.rb +5 -8
  27. data/lib/symmetric_encryption/version.rb +2 -2
  28. data/lib/symmetric_encryption/writer.rb +12 -17
  29. data/test/active_record_test.rb +237 -200
  30. data/test/cipher_test.rb +12 -6
  31. data/test/encoder_test.rb +1 -3
  32. data/test/header_test.rb +0 -4
  33. data/test/key_test.rb +0 -2
  34. data/test/keystore/environment_test.rb +10 -11
  35. data/test/keystore/file_test.rb +9 -10
  36. data/test/keystore_test.rb +2 -3
  37. data/test/mongoid_test.rb +37 -40
  38. data/test/reader_test.rb +24 -32
  39. data/test/symmetric_encryption_test.rb +17 -18
  40. data/test/test_db.sqlite3 +0 -0
  41. data/test/writer_test.rb +0 -1
  42. metadata +23 -23
@@ -76,4 +76,3 @@ module SymmetricEncryption
76
76
  end
77
77
  end
78
78
  end
79
-
@@ -1,5 +1,4 @@
1
1
  module SymmetricEncryption
2
-
3
2
  # Exceptions created by SymmetricEncryption
4
3
  class Error < StandardError
5
4
  end
@@ -11,5 +10,4 @@ module SymmetricEncryption
11
10
  # Exceptions when trying to use the keys before they have been configured
12
11
  class ConfigError < Error
13
12
  end
14
-
15
13
  end
@@ -36,7 +36,11 @@ module ActiveRecord #:nodoc:
36
36
  def self.attr_encrypted(*params)
37
37
  # Ensure ActiveRecord has created all its methods first
38
38
  # Ignore failures since the table may not yet actually exist
39
- define_attribute_methods rescue nil
39
+ begin
40
+ define_attribute_methods
41
+ rescue StandardError
42
+ nil
43
+ end
40
44
 
41
45
  options = params.last.is_a?(Hash) ? params.pop.dup : {}
42
46
 
@@ -102,6 +106,5 @@ module ActiveRecord #:nodoc:
102
106
  def self.encrypted_column?(attribute)
103
107
  encrypted_columns.include?(attribute)
104
108
  end
105
-
106
109
  end
107
110
  end
@@ -16,15 +16,15 @@ module MongoMapper
16
16
  Date => :date,
17
17
  Boolean => :boolean,
18
18
  Hash => :json
19
- }
19
+ }.freeze
20
20
 
21
21
  module ClassMethods
22
- def encrypted_key(key_name, type, full_options={})
22
+ def encrypted_key(key_name, type, full_options = {})
23
23
  full_options = full_options.is_a?(Hash) ? full_options.dup : {}
24
24
  options = full_options.delete(:encrypted) || {}
25
25
  # Support overriding the name of the decrypted attribute
26
26
  encrypted_key_name = options.delete(:encrypt_as) || "encrypted_#{key_name}"
27
- options[:type] = COERCION_MAP[type] unless [:yaml, :json].include?(options[:type])
27
+ options[:type] = COERCION_MAP[type] unless %i[yaml json].include?(options[:type])
28
28
 
29
29
  raise(ArgumentError, "Invalid type: #{type.inspect}. Valid types: #{COERCION_MAP.keys.join(',')}") unless options[:type]
30
30
 
@@ -32,9 +32,7 @@ module MongoMapper
32
32
 
33
33
  key(encrypted_key_name, String, full_options)
34
34
  end
35
-
36
35
  end
37
-
38
36
  end
39
37
  end
40
38
  end
@@ -105,5 +105,3 @@ Mongoid::Fields.option :encrypted do |model, field, options|
105
105
  SymmetricEncryption::Generator.generate_decrypted_accessors(model, decrypted_field_name, encrypted_field_name, options)
106
106
  end
107
107
  end
108
-
109
-
@@ -8,7 +8,7 @@ module SymmetricEncryption
8
8
  compress = options.delete(:compress) || false
9
9
  type = options.delete(:type) || :string
10
10
 
11
- raise(ArgumentError, "SymmetricEncryption Invalid options #{options.inspect} when encrypting '#{decrypted_name}'") if options.size > 0
11
+ raise(ArgumentError, "SymmetricEncryption Invalid options #{options.inspect} when encrypting '#{decrypted_name}'") unless options.empty?
12
12
  raise(ArgumentError, "Invalid type: #{type.inspect}. Valid types: #{SymmetricEncryption::COERCION_TYPES.inspect}") unless SymmetricEncryption::COERCION_TYPES.include?(type)
13
13
 
14
14
  if model.const_defined?(:EncryptedAttributes, _search_ancestors = false)
@@ -19,7 +19,7 @@ module SymmetricEncryption
19
19
  end
20
20
 
21
21
  # Generate getter and setter methods
22
- mod.module_eval(<<-EOS, __FILE__, __LINE__ + 1)
22
+ mod.module_eval(<<~ACCESSORS, __FILE__, __LINE__ + 1)
23
23
  # Set the un-encrypted field
24
24
  # Also updates the encrypted field with the encrypted value
25
25
  # Freeze the decrypted field value so that it is not modified directly
@@ -45,7 +45,7 @@ module SymmetricEncryption
45
45
  def #{decrypted_name}_changed?
46
46
  #{encrypted_name}_changed?
47
47
  end
48
- EOS
48
+ ACCESSORS
49
49
  end
50
50
  end
51
51
  end
@@ -78,7 +78,7 @@ module SymmetricEncryption
78
78
  auth_tag: nil)
79
79
 
80
80
  @version = version
81
- @compress = compress
81
+ @compress = compress
82
82
  @iv = iv
83
83
  @key = key
84
84
  @cipher_name = cipher_name
@@ -111,7 +111,7 @@ module SymmetricEncryption
111
111
  # String to extract the header from
112
112
  def parse!(buffer)
113
113
  offset = parse(buffer)
114
- return if offset == 0
114
+ return if offset.zero?
115
115
  buffer.slice!(0..offset - 1)
116
116
  buffer
117
117
  end
@@ -153,7 +153,13 @@ module SymmetricEncryption
153
153
  self.version = buffer.getbyte(offset)
154
154
  offset += 1
155
155
 
156
- raise(SymmetricEncryption::CipherError, "Cipher with version:#{version.inspect} not found in any of the configured SymmetricEncryption ciphers") unless cipher
156
+ unless cipher
157
+ raise(
158
+ SymmetricEncryption::CipherError,
159
+ "Cipher with version:#{version.inspect} not found in any of the configured SymmetricEncryption ciphers"
160
+ )
161
+ end
162
+
157
163
  flags = buffer.getbyte(offset)
158
164
  offset += 1
159
165
 
@@ -255,6 +261,5 @@ module SymmetricEncryption
255
261
  out = buffer.byteslice(offset, len)
256
262
  [out, offset + len]
257
263
  end
258
-
259
264
  end
260
265
  end
@@ -12,7 +12,7 @@ module SymmetricEncryption
12
12
  # * encrypted_key
13
13
  # * key_filename
14
14
  def self.from_config(key: nil, key_filename: nil, encrypted_key: nil, key_env_var: nil,
15
- iv:, key_encrypting_key: nil, cipher_name: 'aes-256-cbc')
15
+ iv:, key_encrypting_key: nil, cipher_name: 'aes-256-cbc')
16
16
 
17
17
  if key_encrypting_key.is_a?(Hash)
18
18
  # Recurse up the chain returning the parent key_encrypting_key
@@ -21,12 +21,12 @@ module SymmetricEncryption
21
21
 
22
22
  key ||=
23
23
  if encrypted_key
24
- raise(ArgumentError, "Missing mandatory :key_encrypting_key when config includes :encrypted_key") unless key_encrypting_key
24
+ raise(ArgumentError, 'Missing mandatory :key_encrypting_key when config includes :encrypted_key') unless key_encrypting_key
25
25
  Keystore::Memory.new(encrypted_key: encrypted_key, key_encrypting_key: key_encrypting_key).read
26
26
  elsif key_filename
27
27
  Keystore::File.new(file_name: key_filename, key_encrypting_key: key_encrypting_key).read
28
28
  elsif key_env_var
29
- raise(ArgumentError, "Missing mandatory :key_encrypting_key when config includes :key_env_var") unless key_encrypting_key
29
+ raise(ArgumentError, 'Missing mandatory :key_encrypting_key when config includes :key_env_var') unless key_encrypting_key
30
30
  Keystore::Environment.new(key_env_var: key_env_var, key_encrypting_key: key_encrypting_key).read
31
31
  end
32
32
 
@@ -101,6 +101,5 @@ module SymmetricEncryption
101
101
  result = openssl_cipher.update(encrypted_string)
102
102
  result << openssl_cipher.final
103
103
  end
104
-
105
104
  end
106
105
  end
@@ -1,10 +1,11 @@
1
1
  module SymmetricEncryption
2
+ # Encryption keys are secured in Keystores
2
3
  module Keystore
3
- #@formatter:off
4
+ # @formatter:off
4
5
  autoload :Environment, 'symmetric_encryption/keystore/environment'
5
6
  autoload :File, 'symmetric_encryption/keystore/file'
6
7
  autoload :Memory, 'symmetric_encryption/keystore/memory'
7
- #@formatter:on
8
+ # @formatter:on
8
9
 
9
10
  # Returns [Hash] a new configuration file after performing key rotation.
10
11
  #
@@ -44,12 +45,12 @@ module SymmetricEncryption
44
45
 
45
46
  cipher_name = config[:cipher_name] || 'aes-256-cbc'
46
47
  new_key_config =
47
- if config.has_key?(:key_filename)
48
+ if config.key?(:key_filename)
48
49
  key_path = ::File.dirname(config[:key_filename])
49
50
  Keystore::File.new_key_config(key_path: key_path, cipher_name: cipher_name, app_name: app_name, version: version, environment: environment)
50
- elsif config.has_key?(:key_env_var)
51
+ elsif config.key?(:key_env_var)
51
52
  Keystore::Environment.new_key_config(cipher_name: cipher_name, app_name: app_name, version: version, environment: environment)
52
- elsif config.has_key?(:encrypted_key)
53
+ elsif config.key?(:encrypted_key)
53
54
  Keystore::Memory.new_key_config(cipher_name: cipher_name, app_name: app_name, version: version, environment: environment)
54
55
  end
55
56
 
@@ -88,12 +89,12 @@ module SymmetricEncryption
88
89
  key = Key.from_config(config)
89
90
  cipher_name = key.cipher_name
90
91
  new_key_config =
91
- if config.has_key?(:key_filename)
92
+ if config.key?(:key_filename)
92
93
  key_path = ::File.dirname(config[:key_filename])
93
94
  Keystore::File.new_key_config(key_path: key_path, cipher_name: cipher_name, app_name: app_name, version: version, environment: environment, dek: key)
94
- elsif config.has_key?(:key_env_var)
95
+ elsif config.key?(:key_env_var)
95
96
  Keystore::Environment.new_key_config(cipher_name: cipher_name, app_name: app_name, version: version, environment: environment, dek: key)
96
- elsif config.has_key?(:encrypted_key)
97
+ elsif config.key?(:encrypted_key)
97
98
  Keystore::Memory.new_key_config(cipher_name: cipher_name, app_name: app_name, version: version, environment: environment, dek: key)
98
99
  end
99
100
 
@@ -121,6 +122,5 @@ module SymmetricEncryption
121
122
  ]
122
123
  }
123
124
  end
124
-
125
125
  end
126
126
  end
@@ -7,14 +7,14 @@ module SymmetricEncryption
7
7
  # Returns [Hash] initial configuration for heroku.
8
8
  # Displays the keys that need to be added to the heroku environment.
9
9
  def self.new_config(app_name: 'symmetric-encryption',
10
- environments: %i(development test release production),
11
- cipher_name: 'aes-256-cbc')
10
+ environments: %i[development test release production],
11
+ cipher_name: 'aes-256-cbc')
12
12
 
13
13
  configs = {}
14
14
  environments.each do |environment|
15
15
  environment = environment.to_sym
16
16
  configs[environment] =
17
- if %i(development test).include?(environment)
17
+ if %i[development test].include?(environment)
18
18
  Keystore.dev_config
19
19
  else
20
20
  cfg = new_key_config(cipher_name: cipher_name, app_name: app_name, environment: environment)
@@ -35,7 +35,7 @@ module SymmetricEncryption
35
35
  kek = SymmetricEncryption::Key.new(cipher_name: cipher_name)
36
36
  dek ||= SymmetricEncryption::Key.new(cipher_name: cipher_name)
37
37
 
38
- key_env_var = "#{app_name}_#{environment}_v#{version}".upcase.gsub('-', '_')
38
+ key_env_var = "#{app_name}_#{environment}_v#{version}".upcase.tr('-', '_')
39
39
  new(key_env_var: key_env_var, key_encrypting_key: kek).write(dek.key)
40
40
 
41
41
  {
@@ -45,7 +45,7 @@ module SymmetricEncryption
45
45
  iv: dek.iv,
46
46
  key_encrypting_key: {
47
47
  key: kek.key,
48
- iv: kek.iv,
48
+ iv: kek.iv
49
49
  }
50
50
  }
51
51
  end
@@ -75,7 +75,7 @@ module SymmetricEncryption
75
75
  puts
76
76
  puts "Or, if using environment variables on another system set the environment variable as follows:\n\n"
77
77
  puts " export #{key_env_var}=\"#{encoder.encode(encrypted_key)}\"\n\n"
78
- puts "********************************************************************************"
78
+ puts '********************************************************************************'
79
79
  end
80
80
 
81
81
  private
@@ -84,7 +84,6 @@ module SymmetricEncryption
84
84
  def encoder
85
85
  @encoder ||= SymmetricEncryption::Encoder[encoding]
86
86
  end
87
-
88
87
  end
89
88
  end
90
89
  end
@@ -6,15 +6,15 @@ module SymmetricEncryption
6
6
  # Returns [Hash] initial configuration.
7
7
  # Generates the encrypted key file for every environment except development and test.
8
8
  def self.new_config(key_path: '/etc/symmetric-encryption',
9
- app_name: 'symmetric-encryption',
10
- environments: %i(development test release production),
11
- cipher_name: 'aes-256-cbc')
9
+ app_name: 'symmetric-encryption',
10
+ environments: %i[development test release production],
11
+ cipher_name: 'aes-256-cbc')
12
12
 
13
13
  configs = {}
14
14
  environments.each do |environment|
15
15
  environment = environment.to_sym
16
16
  configs[environment] =
17
- if %i(development test).include?(environment)
17
+ if %i[development test].include?(environment)
18
18
  Keystore.dev_config
19
19
  else
20
20
  cfg = new_key_config(key_path: key_path, cipher_name: cipher_name, app_name: app_name, environment: environment)
@@ -84,7 +84,7 @@ module SymmetricEncryption
84
84
 
85
85
  # Read from the file, raising an exception if it is not found
86
86
  def read_from_file
87
- ::File.open(file_name, 'rb') { |f| f.read }
87
+ ::File.open(file_name, 'rb', &:read)
88
88
  rescue Errno::ENOENT
89
89
  raise(SymmetricEncryption::ConfigError, "Symmetric Encryption key file: '#{file_name}' not found or readable")
90
90
  end
@@ -96,7 +96,6 @@ module SymmetricEncryption
96
96
  ::File.rename(file_name, "#{file_name}.#{Time.now.to_i}") if ::File.exist?(file_name)
97
97
  ::File.open(file_name, 'wb') { |file| file.write(data) }
98
98
  end
99
-
100
99
  end
101
100
  end
102
101
  end
@@ -1,5 +1,6 @@
1
1
  module SymmetricEncryption
2
2
  module Keystore
3
+ # In Memory Keystore usually used for testing purposes
3
4
  class Memory
4
5
  attr_accessor :key_encrypting_key
5
6
  attr_reader :encrypted_key
@@ -26,7 +27,7 @@ module SymmetricEncryption
26
27
  iv: iv,
27
28
  key_encrypting_key: {
28
29
  key: kek.key,
29
- iv: kek.iv,
30
+ iv: kek.iv
30
31
  }
31
32
  }
32
33
  end
@@ -47,7 +48,6 @@ module SymmetricEncryption
47
48
  def write(key)
48
49
  self.encrypted_key = key_encrypting_key.encrypt(key)
49
50
  end
50
-
51
51
  end
52
52
  end
53
53
  end
@@ -1,7 +1,5 @@
1
- # encoding: utf-8
2
1
  module SymmetricEncryption #:nodoc:
3
2
  class Railtie < Rails::Railtie #:nodoc:
4
-
5
3
  # Exposes Symmetric Encryption's configuration to the Rails application configuration.
6
4
  #
7
5
  # @example Set up configuration in the Rails app.
@@ -31,23 +29,22 @@ module SymmetricEncryption #:nodoc:
31
29
  config.before_configuration do
32
30
  # Check if already configured
33
31
  unless ::SymmetricEncryption.cipher?
34
- app_name = Rails::Application.subclasses.first.parent.to_s.underscore
32
+ app_name = Rails::Application.subclasses.first.parent.to_s.underscore
35
33
  config_file = Rails.root.join('config', 'symmetric-encryption.yml')
36
34
  if config_file.file?
37
35
  begin
38
- ::SymmetricEncryption::Config.load!(file_name: config_file, env: Rails.env)
36
+ ::SymmetricEncryption::Config.load!(file_name: config_file, env: ENV['SYMMETRIC_ENCRYPTION_ENV'] || Rails.env)
39
37
  rescue ArgumentError => exc
40
38
  puts "\nSymmetric Encryption not able to read keys."
41
39
  puts "#{exc.class.name} #{exc.message}"
42
- puts "To generate a new config file and key files: symmetric-encryption --generate --key-path /etc/#{app_name} --app_name #{app_name}\n\n"
40
+ puts "To generate a new config file and key files: symmetric-encryption --generate --key-path /etc/#{app_name} --app-name #{app_name}\n\n"
43
41
  raise(exc)
44
42
  end
45
43
  else
46
44
  puts "\nSymmetric Encryption config not found."
47
- puts "To generate a new config file and key files: symmetric-encryption --generate --key-path /etc/#{app_name} --app_name #{app_name}\n\n"
45
+ puts "To generate a new config file and key files: symmetric-encryption --generate --key-path /etc/#{app_name} --app-name #{app_name}\n\n"
48
46
  end
49
47
  end
50
48
  end
51
-
52
49
  end
53
50
  end
@@ -13,6 +13,7 @@
13
13
  # # => true
14
14
  class SymmetricEncryptionValidator < ActiveModel::EachValidator
15
15
  def validate_each(record, attribute, value)
16
- record.errors.add(attribute, 'must be a value encrypted using SymmetricEncryption.encrypt') unless SymmetricEncryption.encrypted?(value)
16
+ return if value.blank? || SymmetricEncryption.encrypted?(value)
17
+ record.errors.add(attribute, 'must be a value encrypted using SymmetricEncryption.encrypt')
17
18
  end
18
19
  end
@@ -59,11 +59,11 @@ module SymmetricEncryption
59
59
  # ensure
60
60
  # csv.close if csv
61
61
  # end
62
- def self.open(file_name_or_stream, buffer_size: 16384, **args, &block)
62
+ def self.open(file_name_or_stream, buffer_size: 16_384, **args, &block)
63
63
  ios = file_name_or_stream.is_a?(String) ? ::File.open(file_name_or_stream, 'rb') : file_name_or_stream
64
64
 
65
65
  begin
66
- file = self.new(ios, buffer_size: buffer_size, **args)
66
+ file = new(ios, buffer_size: buffer_size, **args)
67
67
  file = Zlib::GzipReader.new(file) if !file.eof? && file.compressed?
68
68
  block ? block.call(file) : file
69
69
  ensure
@@ -76,7 +76,7 @@ module SymmetricEncryption
76
76
  # Notes:
77
77
  # * Do not use this method for reading large files.
78
78
  def self.read(file_name_or_stream, **args)
79
- open(file_name_or_stream, **args) { |f| f.read }
79
+ self.open(file_name_or_stream, **args, &:read)
80
80
  end
81
81
 
82
82
  # Decrypt an entire file.
@@ -97,23 +97,21 @@ module SymmetricEncryption
97
97
  #
98
98
  # Notes:
99
99
  # * The file contents are streamed so that the entire file is _not_ loaded into memory.
100
- def self.decrypt(source:, target:, block_size: 65535, **args)
100
+ def self.decrypt(source:, target:, block_size: 65_535, **args)
101
101
  target_ios = target.is_a?(String) ? ::File.open(target, 'wb') : target
102
102
  bytes_written = 0
103
- open(source, **args) do |input_ios|
104
- while !input_ios.eof?
105
- bytes_written += target_ios.write(input_ios.read(block_size))
106
- end
103
+ self.open(source, **args) do |input_ios|
104
+ bytes_written += target_ios.write(input_ios.read(block_size)) until input_ios.eof?
107
105
  end
108
106
  bytes_written
109
107
  ensure
110
- target_ios.close if target_ios && target_ios.respond_to?(:closed?) && !target_ios.closed?
108
+ target_ios.close if target_ios&.respond_to?(:closed?) && !target_ios.closed?
111
109
  end
112
110
 
113
111
  # Returns [true|false] whether the file or stream contains any data
114
112
  # excluding the header should it have one
115
113
  def self.empty?(file_name_or_stream)
116
- open(file_name_or_stream) { |file| file.eof? }
114
+ open(file_name_or_stream, &:eof?)
117
115
  end
118
116
 
119
117
  # Returns [true|false] whether the file contains the encryption header
@@ -161,9 +159,7 @@ module SymmetricEncryption
161
159
  #
162
160
  # Note: When no header is present, the version is set to the one supplied
163
161
  # in the options
164
- def version
165
- @version
166
- end
162
+ attr_reader :version
167
163
 
168
164
  # Close the IO Stream
169
165
  #
@@ -198,19 +194,17 @@ module SymmetricEncryption
198
194
  #
199
195
  # At end of file, it returns nil if no more data is available, or the last
200
196
  # remaining bytes
201
- def read(length=nil)
197
+ def read(length = nil)
202
198
  data = nil
203
199
  if length
204
- return '' if length == 0
200
+ return '' if length.zero?
205
201
  return nil if eof?
206
202
  # Read length bytes
207
- while (@read_buffer.length < length) && !@ios.eof?
208
- read_block
209
- end
210
- if @read_buffer.length == 0
203
+ read_block while (@read_buffer.length < length) && !@ios.eof?
204
+ if @read_buffer.empty?
211
205
  data = nil
212
206
  elsif @read_buffer.length > length
213
- data = @read_buffer.slice!(0..length-1)
207
+ data = @read_buffer.slice!(0..length - 1)
214
208
  else
215
209
  data = @read_buffer
216
210
  @read_buffer = ''
@@ -220,10 +214,10 @@ module SymmetricEncryption
220
214
  data = @read_buffer
221
215
  @read_buffer = ''
222
216
 
223
- if !@ios.eof?
217
+ unless @ios.eof?
224
218
  # Read entire file
225
219
  buf = @ios.read || ''
226
- data << @stream_cipher.update(buf) if buf && buf.length > 0
220
+ data << @stream_cipher.update(buf) if buf && !buf.empty?
227
221
  data << @stream_cipher.final
228
222
  end
229
223
  end
@@ -235,14 +229,14 @@ module SymmetricEncryption
235
229
  # Raises EOFError on eof
236
230
  # The stream must be opened for reading or an IOError will be raised.
237
231
  def readline(sep_string = "\n")
238
- gets(sep_string) || raise(EOFError.new('End of file reached when trying to read a line'))
232
+ gets(sep_string) || raise(EOFError, 'End of file reached when trying to read a line')
239
233
  end
240
234
 
241
235
  # Reads a single decrypted line from the file up to and including the optional sep_string.
242
236
  # A sep_string of nil reads the entire contents of the file
243
237
  # Returns nil on eof
244
238
  # The stream must be opened for reading or an IOError will be raised.
245
- def gets(sep_string, length=nil)
239
+ def gets(sep_string, length = nil)
246
240
  return read(length) if sep_string.nil?
247
241
 
248
242
  # Read more data until we get the sep_string
@@ -253,7 +247,7 @@ module SymmetricEncryption
253
247
  index ||= -1
254
248
  data = @read_buffer.slice!(0..index)
255
249
  @pos += data.length
256
- return nil if data.length == 0 && eof?
250
+ return nil if data.empty? && eof?
257
251
  data
258
252
  end
259
253
 
@@ -262,23 +256,19 @@ module SymmetricEncryption
262
256
  # Executes the block for every line in ios, where lines are separated by sep_string.
263
257
  # ios must be opened for reading or an IOError will be raised.
264
258
  def each_line(sep_string = "\n")
265
- while !eof?
266
- yield gets(sep_string)
267
- end
259
+ yield gets(sep_string) until eof?
268
260
  self
269
261
  end
270
262
 
271
- alias_method :each, :each_line
263
+ alias each each_line
272
264
 
273
265
  # Returns whether the end of file has been reached for this stream
274
266
  def eof?
275
- (@read_buffer.size == 0) && @ios.eof?
267
+ @read_buffer.empty? && @ios.eof?
276
268
  end
277
269
 
278
270
  # Return the number of bytes read so far from the input stream
279
- def pos
280
- @pos
281
- end
271
+ attr_reader :pos
282
272
 
283
273
  # Rewind back to the beginning of the file
284
274
  def rewind
@@ -299,7 +289,7 @@ module SymmetricEncryption
299
289
  # then re-read upto the point specified
300
290
  # WARNING: IO::SEEK_END will read the entire file and then again
301
291
  # upto the point specified
302
- def seek(amount, whence=IO::SEEK_SET)
292
+ def seek(amount, whence = IO::SEEK_SET)
303
293
  offset = 0
304
294
  case whence
305
295
  when IO::SEEK_SET
@@ -317,7 +307,7 @@ module SymmetricEncryption
317
307
  # Read and decrypt entire file a block at a time to get its total
318
308
  # unencrypted size
319
309
  size = 0
320
- while !eof
310
+ until eof
321
311
  read_block
322
312
  size += @read_buffer.size
323
313
  @read_buffer = ''
@@ -327,7 +317,7 @@ module SymmetricEncryption
327
317
  else
328
318
  raise(ArgumentError, "unknown whence:#{whence} supplied to seek()")
329
319
  end
330
- read(offset) if offset > 0
320
+ read(offset) if offset.positive?
331
321
  0
332
322
  end
333
323
 
@@ -364,7 +354,7 @@ module SymmetricEncryption
364
354
  @stream_cipher.iv = iv || cipher.iv
365
355
 
366
356
  # First call to #update should return an empty string anyway
367
- if buf && buf.length > 0
357
+ if buf && !buf.empty?
368
358
  @read_buffer = @stream_cipher.update(buf)
369
359
  @read_buffer << @stream_cipher.final if @ios.eof?
370
360
  else
@@ -375,13 +365,12 @@ module SymmetricEncryption
375
365
  # Read a block of data and append the decrypted data in the read buffer
376
366
  def read_block
377
367
  buf = @ios.read(@buffer_size)
378
- @read_buffer << @stream_cipher.update(buf) if buf && buf.length > 0
368
+ @read_buffer << @stream_cipher.update(buf) if buf && !buf.empty?
379
369
  @read_buffer << @stream_cipher.final if @ios.eof?
380
370
  end
381
371
 
382
372
  def closed?
383
373
  @closed || @ios.respond_to?(:closed?) && @ios.closed?
384
374
  end
385
-
386
375
  end
387
376
  end