symmetric-encryption 4.1.0.beta1 → 4.1.0

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/symmetric_encryption/cipher.rb +9 -2
  3. data/lib/symmetric_encryption/cli.rb +13 -6
  4. data/lib/symmetric_encryption/config.rb +9 -6
  5. data/lib/symmetric_encryption/encoder.rb +6 -0
  6. data/lib/symmetric_encryption/extensions/mongoid/encrypted.rb +1 -0
  7. data/lib/symmetric_encryption/generator.rb +1 -1
  8. data/lib/symmetric_encryption/header.rb +7 -5
  9. data/lib/symmetric_encryption/key.rb +2 -0
  10. data/lib/symmetric_encryption/keystore/aws.rb +9 -9
  11. data/lib/symmetric_encryption/keystore/environment.rb +3 -2
  12. data/lib/symmetric_encryption/keystore/file.rb +1 -1
  13. data/lib/symmetric_encryption/keystore/memory.rb +1 -1
  14. data/lib/symmetric_encryption/keystore.rb +15 -16
  15. data/lib/symmetric_encryption/railtie.rb +7 -2
  16. data/lib/symmetric_encryption/railties/symmetric_encryption_validator.rb +1 -0
  17. data/lib/symmetric_encryption/reader.rb +50 -58
  18. data/lib/symmetric_encryption/symmetric_encryption.rb +2 -1
  19. data/lib/symmetric_encryption/utils/aws.rb +6 -4
  20. data/lib/symmetric_encryption/utils/re_encrypt_files.rb +2 -2
  21. data/lib/symmetric_encryption/version.rb +1 -1
  22. data/lib/symmetric_encryption/writer.rb +33 -27
  23. data/lib/symmetric_encryption.rb +26 -5
  24. data/test/active_record_test.rb +25 -25
  25. data/test/cipher_test.rb +3 -3
  26. data/test/header_test.rb +1 -1
  27. data/test/keystore/aws_test.rb +7 -7
  28. data/test/keystore/file_test.rb +1 -1
  29. data/test/keystore_test.rb +2 -2
  30. data/test/mongoid_test.rb +15 -15
  31. data/test/reader_test.rb +28 -8
  32. data/test/symmetric_encryption_test.rb +2 -2
  33. data/test/test_db.sqlite3 +0 -0
  34. data/test/utils/aws_test.rb +1 -2
  35. data/test/writer_test.rb +48 -46
  36. metadata +23 -23
data/test/cipher_test.rb CHANGED
@@ -93,7 +93,7 @@ class CipherTest < Minitest::Test
93
93
  always_add_header: always_add_header
94
94
  )
95
95
 
96
- h = @encrypted_values[cipher_name][encoding] if @encrypted_values[cipher_name]
96
+ h = @encrypted_values[cipher_name][encoding] if @encrypted_values[cipher_name]
97
97
  skip "Add @encrypted_values for cipher_name: #{cipher_name} and encoding: #{encoding}, value: #{@cipher.encrypt(@social_security_number).inspect}" unless h
98
98
  @social_security_number_encrypted = h[always_add_header ? :header : :no_header]
99
99
 
@@ -150,7 +150,7 @@ class CipherTest < Minitest::Test
150
150
 
151
151
  describe 'with configuration' do
152
152
  before do
153
- @cipher = SymmetricEncryption::Cipher.new(
153
+ @cipher = SymmetricEncryption::Cipher.new(
154
154
  key: '1234567890ABCDEF',
155
155
  iv: '1234567890ABCDEF',
156
156
  cipher_name: 'aes-128-cbc',
@@ -181,7 +181,7 @@ class CipherTest < Minitest::Test
181
181
  key.key,
182
182
  key.cipher_name
183
183
  )
184
- header = SymmetricEncryption::Header.new
184
+ header = SymmetricEncryption::Header.new
185
185
  header.parse(binary_header)
186
186
  assert_equal true, header.compressed?
187
187
  assert random_cipher = SymmetricEncryption::Cipher.new(iv: key.iv, key: key.key, cipher_name: key.cipher_name)
data/test/header_test.rb CHANGED
@@ -179,7 +179,7 @@ class CipherTest < Minitest::Test
179
179
  end
180
180
 
181
181
  it 'encrypted string' do
182
- header = SymmetricEncryption::Header.new
182
+ header = SymmetricEncryption::Header.new
183
183
  assert remainder = header.parse!(binary_encrypted_value)
184
184
  assert_equal SymmetricEncryption.cipher.version, header.version
185
185
  refute header.compressed?
@@ -13,7 +13,7 @@ module SymmetricEncryption
13
13
  end
14
14
 
15
15
  let :the_test_path do
16
- path = "tmp/keystore/aws_test"
16
+ path = 'tmp/keystore/aws_test'
17
17
  FileUtils.makedirs(path) unless ::File.exist?(path)
18
18
  path
19
19
  end
@@ -72,24 +72,24 @@ module SymmetricEncryption
72
72
  end
73
73
 
74
74
  it 'creates encrypted key file for every region' do
75
- assert key_files = key_config[:key_files]
75
+ assert key_files = key_config[:key_files]
76
76
  common_data_key = nil
77
77
  first_encrypted_data_key = nil
78
78
 
79
- master_key_alias = "alias/symmetric-encryption/tester/test"
79
+ master_key_alias = 'alias/symmetric-encryption/tester/test'
80
80
 
81
81
  key_files.each do |key_file|
82
- assert region = key_file[:region]
83
- assert file_name = key_file[:file_name]
82
+ assert region = key_file[:region]
83
+ assert file_name = key_file[:file_name]
84
84
  expected_file_name = "#{the_test_path}/tester_test_#{region}_v11.encrypted_key"
85
85
 
86
86
  assert_equal expected_file_name, file_name
87
87
  assert ::File.exist?(file_name)
88
88
 
89
89
  assert encoded_data_key = ::File.read(file_name)
90
- encrypted_data_key = Base64.strict_decode64(encoded_data_key)
90
+ encrypted_data_key = Base64.strict_decode64(encoded_data_key)
91
91
 
92
- aws = SymmetricEncryption::Utils::Aws.new(region: region, master_key_alias: master_key_alias)
92
+ aws = SymmetricEncryption::Utils::Aws.new(region: region, master_key_alias: master_key_alias)
93
93
  assert data_key = aws.decrypt(encrypted_data_key)
94
94
 
95
95
  # Verify that the dek is the same in every region, but encrypted with the CMK for that region.
@@ -5,7 +5,7 @@ module SymmetricEncryption
5
5
  class FileTest < Minitest::Test
6
6
  describe SymmetricEncryption::Keystore::File do
7
7
  let :the_test_path do
8
- path = "tmp/keystore/file_test"
8
+ path = 'tmp/keystore/file_test'
9
9
  FileUtils.makedirs(path) unless ::File.exist?(path)
10
10
  path
11
11
  end
@@ -8,7 +8,7 @@ module SymmetricEncryption
8
8
  end
9
9
 
10
10
  let :the_test_path do
11
- path = "tmp/keystore_test"
11
+ path = 'tmp/keystore_test'
12
12
  FileUtils.makedirs(path) unless ::File.exist?(path)
13
13
  path
14
14
  end
@@ -119,7 +119,7 @@ module SymmetricEncryption
119
119
  assert ciphers = key_rotation[env.to_sym][:ciphers], "Environment #{env} is missing ciphers: #{key_rotation[env.to_sym].inspect}"
120
120
  assert_equal 2, ciphers.size, "Environment #{env}: #{ciphers.inspect}"
121
121
  assert new_config = ciphers.first
122
- assert file_name = new_config[:key_filename], "Environment #{env} is missing key_filename: #{ciphers.inspect}"
122
+ assert file_name = new_config[:key_filename], "Environment #{env} is missing key_filename: #{ciphers.inspect}"
123
123
  assert File.exist?(file_name)
124
124
  assert_equal 2, new_config[:version]
125
125
  end
data/test/mongoid_test.rb CHANGED
@@ -85,17 +85,17 @@ begin
85
85
  encrypted_social_security_number: @social_security_number_encrypted,
86
86
  name: 'Joe Bloggs',
87
87
  # data type specific fields
88
- integer_value: @integer_value,
89
- aliased_integer_value: @integer_value,
90
- float_value: @float_value,
91
- decimal_value: @decimal_value,
92
- datetime_value: @datetime_value,
93
- time_value: @time_value,
94
- date_value: @date_value,
95
- true_value: true,
96
- false_value: false,
97
- data_yaml: @h.dup,
98
- data_json: @h.dup
88
+ integer_value: @integer_value,
89
+ aliased_integer_value: @integer_value,
90
+ float_value: @float_value,
91
+ decimal_value: @decimal_value,
92
+ datetime_value: @datetime_value,
93
+ time_value: @time_value,
94
+ date_value: @date_value,
95
+ true_value: true,
96
+ false_value: false,
97
+ data_yaml: @h.dup,
98
+ data_json: @h.dup
99
99
  )
100
100
  end
101
101
 
@@ -144,17 +144,17 @@ begin
144
144
 
145
145
  it 'support same iv' do
146
146
  @user.social_security_number = @social_security_number
147
- assert first_value = @user.social_security_number
147
+ assert first_value = @user.social_security_number
148
148
  # Assign the same value
149
149
  @user.social_security_number = @social_security_number
150
150
  assert_equal first_value, @user.social_security_number
151
151
  end
152
152
 
153
153
  it 'support a random iv' do
154
- @user.string = @string
154
+ @user.string = @string
155
155
  assert first_value = @user.encrypted_string
156
- @user.string = 'blah'
157
- @user.string = @string.dup
156
+ @user.string = 'blah'
157
+ @user.string = @string.dup
158
158
  refute_equal first_value, @user.encrypted_string
159
159
  end
160
160
 
data/test/reader_test.rb CHANGED
@@ -6,7 +6,7 @@ require 'stringio'
6
6
  class ReaderTest < Minitest::Test
7
7
  describe SymmetricEncryption::Reader do
8
8
  before do
9
- @data = [
9
+ @data = [
10
10
  "Hello World\n",
11
11
  "Keep this secret\n",
12
12
  'And keep going even further and further...'
@@ -17,7 +17,7 @@ class ReaderTest < Minitest::Test
17
17
  @cipher = SymmetricEncryption.cipher(0)
18
18
  @data_encrypted_without_header = @cipher.binary_encrypt(@data_str, header: false)
19
19
 
20
- header = SymmetricEncryption::Header.new(
20
+ header = SymmetricEncryption::Header.new(
21
21
  version: @cipher.version,
22
22
  iv: @cipher.iv,
23
23
  key: @cipher.send(:key),
@@ -87,7 +87,7 @@ class ReaderTest < Minitest::Test
87
87
 
88
88
  [
89
89
  # No Header
90
- {header: false, random_key: false, random_iv: false},
90
+ {header: false, random_key: false, random_iv: false, compress: false},
91
91
  # Default Header with random key and iv
92
92
  {},
93
93
  # Header with no compression ( default anyway )
@@ -184,6 +184,26 @@ class ReaderTest < Minitest::Test
184
184
  end
185
185
  end
186
186
 
187
+ it '#read(size, outbuf)' do
188
+ file = SymmetricEncryption::Reader.open(@file_name)
189
+ # Not supported with compressed files
190
+ if file.is_a?(SymmetricEncryption::Reader)
191
+ eof = file.eof?
192
+ output_buffer = 'buffer'
193
+ data = file.read(4096, output_buffer)
194
+ file.close
195
+
196
+ assert_equal @eof, eof
197
+ if @data_size.positive?
198
+ assert_equal @data_str, data
199
+ assert_equal data.object_id, output_buffer.object_id
200
+ else
201
+ assert_nil data
202
+ assert_empty output_buffer
203
+ end
204
+ end
205
+ end
206
+
187
207
  it '#each_line' do
188
208
  SymmetricEncryption::Reader.open(@file_name) do |file|
189
209
  i = 0
@@ -212,9 +232,9 @@ class ReaderTest < Minitest::Test
212
232
  assert_equal @eof, eof
213
233
  if @data_size.positive?
214
234
  assert_equal @data_str, data
235
+ elsif defined?(JRuby)
215
236
  # On JRuby Zlib::GzipReader.new(file) returns '' instead of nil on an empty file
216
- elsif defined?(JRuby) && options[:compress] && (usecase == :empty)
217
- assert_equal '', data
237
+ assert data.blank?
218
238
  else
219
239
  assert_nil data
220
240
  end
@@ -222,7 +242,7 @@ class ReaderTest < Minitest::Test
222
242
 
223
243
  it '#gets(delim)' do
224
244
  SymmetricEncryption::Reader.open(@file_name) do |file|
225
- i = 0
245
+ i = 0
226
246
  while (line = file.gets("\n"))
227
247
  assert_equal @data[i], line
228
248
  i += 1
@@ -233,7 +253,7 @@ class ReaderTest < Minitest::Test
233
253
 
234
254
  it '#gets(delim,size)' do
235
255
  SymmetricEncryption::Reader.open(@file_name) do |file|
236
- i = 0
256
+ i = 0
237
257
  i += 1 while file.gets("\n", 128)
238
258
  assert_equal (@data_size.positive? ? 3 : 0), i
239
259
  end
@@ -284,7 +304,7 @@ class ReaderTest < Minitest::Test
284
304
  before do
285
305
  @file_name = '_test'
286
306
  # Create encrypted file with old encryption key
287
- SymmetricEncryption::Writer.open(@file_name, version: 0, header: false, random_key: false, random_iv: false) do |file|
307
+ SymmetricEncryption::Writer.open(@file_name, version: 0, header: false, random_key: false, random_iv: false, compress: false) do |file|
288
308
  @data.inject(0) { |sum, str| sum + file.write(str) }
289
309
  end
290
310
  end
@@ -6,7 +6,7 @@ class SymmetricEncryptionTest < Minitest::Test
6
6
  describe 'SymmetricEncryption' do
7
7
  describe 'configuration' do
8
8
  before do
9
- config = SymmetricEncryption::Config.new(
9
+ config = SymmetricEncryption::Config.new(
10
10
  file_name: File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'),
11
11
  env: 'test'
12
12
  )
@@ -146,7 +146,7 @@ class SymmetricEncryptionTest < Minitest::Test
146
146
  before do
147
147
  @social_security_number = '987654321'
148
148
  # Encrypt data without a header and encode with base64 which has a trailing '\n'
149
- no_header = SymmetricEncryption.cipher(0).binary_encrypt(@social_security_number, header: false)
149
+ no_header = SymmetricEncryption.cipher(0).binary_encrypt(@social_security_number, header: false)
150
150
  assert @encrypted_0_ssn = SymmetricEncryption.cipher(0).encode(no_header)
151
151
  end
152
152
 
data/test/test_db.sqlite3 CHANGED
Binary file
@@ -36,7 +36,7 @@ module SymmetricEncryption
36
36
 
37
37
  describe '#create_master_key' do
38
38
  it 'creates a new master key' do
39
- skip "Only run if really needed, gets tested once as part of the CMK auto-create"
39
+ skip 'Only run if really needed, gets tested once as part of the CMK auto-create'
40
40
  aws.delete_master_key(retention_days: 7)
41
41
  aws.create_master_key
42
42
  end
@@ -68,7 +68,6 @@ module SymmetricEncryption
68
68
  assert_equal message, decrypted
69
69
  end
70
70
  end
71
-
72
71
  end
73
72
  end
74
73
  end
data/test/writer_test.rb CHANGED
@@ -6,7 +6,7 @@ require 'stringio'
6
6
  class WriterTest < Minitest::Test
7
7
  describe SymmetricEncryption::Writer do
8
8
  before do
9
- @data = [
9
+ @data = [
10
10
  "Hello World\n",
11
11
  "Keep this secret\n",
12
12
  'And keep going even further and further...'
@@ -22,55 +22,57 @@ class WriterTest < Minitest::Test
22
22
  File.delete(@source_file_name) if File.exist?(@source_file_name)
23
23
  end
24
24
 
25
- describe '#write' do
26
- it 'encrypt to string stream' do
27
- stream = StringIO.new
28
- file = SymmetricEncryption::Writer.new(stream)
29
- written_len = @data.inject(0) { |sum, str| sum + file.write(str) }
30
- assert_equal @data_len, file.size
31
- file.close
25
+ [true, false, nil].each do |compress|
26
+ describe "compress: #{compress.inspect}" do
27
+ describe '.open' do
28
+ it 'encrypt to stream' do
29
+ written_len = 0
30
+ stream = StringIO.new
31
+ SymmetricEncryption::Writer.open(stream, compress: compress) do |file|
32
+ written_len = @data.inject(0) { |sum, str| sum + file.write(str) }
33
+ end
34
+ size = stream.string.size
35
+ if compress == false
36
+ assert @data_len, size
37
+ else
38
+ # With small files the compressed file is larger
39
+ assert size >= @data_len
40
+ end
41
+ assert_equal @data_len, written_len
42
+ end
32
43
 
33
- assert_equal @data_len, written_len
34
- assert_equal @data_str, SymmetricEncryption::Reader.read(StringIO.new(stream.string))
35
- end
36
- end
37
-
38
- describe '.open' do
39
- it 'encrypt to stream' do
40
- written_len = 0
41
- stream = StringIO.new
42
- SymmetricEncryption::Writer.open(stream) do |file|
43
- written_len = @data.inject(0) { |sum, str| sum + file.write(str) }
44
- assert_equal @data_len, file.size
45
- end
46
- assert_equal @data_len, written_len
47
- end
48
-
49
- it 'encrypt to file' do
50
- written_len = nil
51
- SymmetricEncryption::Writer.open(@file_name) do |file|
52
- written_len = @data.inject(0) { |sum, str| sum + file.write(str) }
53
- assert_equal @data_len, file.size
44
+ it 'encrypt to file' do
45
+ written_len = SymmetricEncryption::Writer.open(@file_name, compress: compress) do |file|
46
+ @data.inject(0) { |sum, str| sum + file.write(str) }
47
+ end
48
+ assert_equal @data_len, written_len
49
+ size = File.size(@file_name)
50
+ if compress == false
51
+ assert @data_len, size
52
+ else
53
+ # With small files the compressed file is larger
54
+ assert size >= @data_len
55
+ end
56
+ assert_equal @data_str, SymmetricEncryption::Reader.read(@file_name)
57
+ end
54
58
  end
55
- assert_equal @data_len, written_len
56
- assert_equal @data_str, SymmetricEncryption::Reader.read(@file_name)
57
- end
58
- end
59
59
 
60
- describe '.encrypt' do
61
- it 'stream' do
62
- target_stream = StringIO.new
63
- source_stream = StringIO.new(@data_str)
64
- source_bytes = SymmetricEncryption::Writer.encrypt(source: source_stream, target: target_stream)
65
- assert_equal @data_len, source_bytes
66
- assert_equal @data_str, SymmetricEncryption::Reader.read(StringIO.new(target_stream.string))
67
- end
60
+ describe '.encrypt' do
61
+ it 'stream' do
62
+ target_stream = StringIO.new
63
+ source_stream = StringIO.new(@data_str)
64
+ source_bytes = SymmetricEncryption::Writer.encrypt(source: source_stream, target: target_stream, compress: compress)
65
+ assert_equal @data_len, source_bytes
66
+ assert_equal @data_str, SymmetricEncryption::Reader.read(StringIO.new(target_stream.string))
67
+ end
68
68
 
69
- it 'file' do
70
- File.open(@source_file_name, 'wb') { |f| f.write(@data_str) }
71
- source_bytes = SymmetricEncryption::Writer.encrypt(source: @source_file_name, target: @file_name)
72
- assert_equal @data_len, source_bytes
73
- assert_equal @data_str, SymmetricEncryption::Reader.read(@file_name)
69
+ it 'file' do
70
+ File.open(@source_file_name, 'wb') { |f| f.write(@data_str) }
71
+ source_bytes = SymmetricEncryption::Writer.encrypt(source: @source_file_name, target: @file_name, compress: compress)
72
+ assert_equal @data_len, source_bytes
73
+ assert_equal @data_str, SymmetricEncryption::Reader.read(@file_name)
74
+ end
75
+ end
74
76
  end
75
77
  end
76
78
  end
metadata CHANGED
@@ -1,30 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: symmetric-encryption
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0.beta1
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-13 00:00:00.000000000 Z
11
+ date: 2018-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: coercible
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
18
  version: '1.0'
20
- type: :runtime
19
+ name: coercible
21
20
  prerelease: false
21
+ type: :runtime
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
- description:
27
+ description:
28
28
  email:
29
29
  - reidmo@gmail.com
30
30
  executables:
@@ -95,7 +95,7 @@ homepage: http://rocketjob.github.io/symmetric-encryption/
95
95
  licenses:
96
96
  - Apache-2.0
97
97
  metadata: {}
98
- post_install_message:
98
+ post_install_message:
99
99
  rdoc_options: []
100
100
  require_paths:
101
101
  - lib
@@ -106,22 +106,33 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
106
  version: '2.3'
107
107
  required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - ">"
109
+ - - ">="
110
110
  - !ruby/object:Gem::Version
111
- version: 1.3.1
111
+ version: '0'
112
112
  requirements: []
113
- rubyforge_project:
113
+ rubyforge_project:
114
114
  rubygems_version: 2.7.6
115
- signing_key:
115
+ signing_key:
116
116
  specification_version: 4
117
117
  summary: Encrypt ActiveRecord and Mongoid attributes, files and passwords in configuration
118
118
  files.
119
119
  test_files:
120
+ - test/symmetric_encryption_test.rb
121
+ - test/test_db.sqlite3
122
+ - test/mongoid_test.rb
123
+ - test/active_record_test.rb
124
+ - test/keystore_test.rb
125
+ - test/reader_test.rb
126
+ - test/encoder_test.rb
127
+ - test/key_test.rb
128
+ - test/header_test.rb
129
+ - test/test_helper.rb
130
+ - test/writer_test.rb
131
+ - test/cipher_test.rb
120
132
  - test/keystore/environment_test.rb
121
133
  - test/keystore/file_test.rb
122
134
  - test/keystore/heroku_test.rb
123
135
  - test/keystore/aws_test.rb
124
- - test/symmetric_encryption_test.rb
125
136
  - test/config/test_secondary_1.key
126
137
  - test/config/mongoid.yml
127
138
  - test/config/test_new.iv
@@ -131,15 +142,4 @@ test_files:
131
142
  - test/config/symmetric-encryption.yml
132
143
  - test/config/empty.csv
133
144
  - test/config/mongo_mapper.yml
134
- - test/test_db.sqlite3
135
- - test/mongoid_test.rb
136
- - test/active_record_test.rb
137
- - test/keystore_test.rb
138
- - test/reader_test.rb
139
- - test/encoder_test.rb
140
145
  - test/utils/aws_test.rb
141
- - test/key_test.rb
142
- - test/header_test.rb
143
- - test/test_helper.rb
144
- - test/writer_test.rb
145
- - test/cipher_test.rb