symmetric-encryption 4.1.0.beta1 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
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