symmetric-encryption 4.0.1 → 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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -7
  3. data/lib/symmetric_encryption/cipher.rb +11 -4
  4. data/lib/symmetric_encryption/cli.rb +39 -28
  5. data/lib/symmetric_encryption/config.rb +9 -6
  6. data/lib/symmetric_encryption/encoder.rb +6 -0
  7. data/lib/symmetric_encryption/extensions/mongoid/encrypted.rb +1 -0
  8. data/lib/symmetric_encryption/generator.rb +1 -1
  9. data/lib/symmetric_encryption/header.rb +7 -5
  10. data/lib/symmetric_encryption/key.rb +2 -62
  11. data/lib/symmetric_encryption/keystore/aws.rb +172 -0
  12. data/lib/symmetric_encryption/keystore/environment.rb +7 -30
  13. data/lib/symmetric_encryption/keystore/file.rb +8 -30
  14. data/lib/symmetric_encryption/keystore/heroku.rb +22 -0
  15. data/lib/symmetric_encryption/keystore/memory.rb +4 -3
  16. data/lib/symmetric_encryption/keystore.rb +151 -36
  17. data/lib/symmetric_encryption/railtie.rb +9 -4
  18. data/lib/symmetric_encryption/railties/symmetric_encryption_validator.rb +1 -0
  19. data/lib/symmetric_encryption/reader.rb +50 -58
  20. data/lib/symmetric_encryption/symmetric_encryption.rb +2 -1
  21. data/lib/symmetric_encryption/utils/aws.rb +141 -0
  22. data/lib/symmetric_encryption/utils/re_encrypt_files.rb +12 -5
  23. data/lib/symmetric_encryption/version.rb +1 -1
  24. data/lib/symmetric_encryption/writer.rb +33 -27
  25. data/lib/symmetric_encryption.rb +27 -6
  26. data/test/active_record_test.rb +25 -25
  27. data/test/cipher_test.rb +3 -3
  28. data/test/header_test.rb +1 -1
  29. data/test/key_test.rb +0 -157
  30. data/test/keystore/aws_test.rb +133 -0
  31. data/test/keystore/environment_test.rb +3 -51
  32. data/test/keystore/file_test.rb +13 -52
  33. data/test/keystore/heroku_test.rb +70 -0
  34. data/test/keystore_test.rb +200 -4
  35. data/test/mongoid_test.rb +15 -15
  36. data/test/reader_test.rb +28 -8
  37. data/test/symmetric_encryption_test.rb +2 -2
  38. data/test/test_db.sqlite3 +0 -0
  39. data/test/test_helper.rb +1 -0
  40. data/test/utils/aws_test.rb +74 -0
  41. data/test/writer_test.rb +48 -46
  42. metadata +29 -20
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
data/test/test_helper.rb CHANGED
@@ -6,6 +6,7 @@ require 'minitest/stub_any_instance'
6
6
  require 'awesome_print'
7
7
  require 'active_record'
8
8
  require 'symmetric-encryption'
9
+ require 'fileutils'
9
10
 
10
11
  # Load Symmetric Encryption keys
11
12
  SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
@@ -0,0 +1,74 @@
1
+ require_relative '../test_helper'
2
+ require 'stringio'
3
+
4
+ module SymmetricEncryption
5
+ module Utils
6
+ class AwsTest < Minitest::Test
7
+ describe SymmetricEncryption::Utils::Aws do
8
+ before do
9
+ unless (ENV['AWS_ACCESS_KEY_ID'] && ENV['AWS_SECRET_ACCESS_KEY']) || ENV['AWS_CONFIG_FILE']
10
+ # For example: export AWS_CONFIG_FILE=~/.aws/credentials
11
+ skip 'Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or AWS_CONFIG_FILE to run AWS KMS tests'
12
+ end
13
+ end
14
+
15
+ let :region do
16
+ 'us-east-1'
17
+ end
18
+
19
+ let :master_key_alias do
20
+ 'alias/symmetric-encryption/test'
21
+ end
22
+
23
+ let :aws do
24
+ SymmetricEncryption::Utils::Aws.new(region: region, master_key_alias: master_key_alias)
25
+ end
26
+
27
+ describe '#key_spec' do
28
+ it 'converts aes-256-cbc' do
29
+ assert_equal 'AES_256', aws.key_spec('aes-256-cbc')
30
+ end
31
+
32
+ it 'converts aes-128-cbc' do
33
+ assert_equal 'AES_128', aws.key_spec('aes-128-cbc')
34
+ end
35
+ end
36
+
37
+ describe '#create_master_key' do
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'
40
+ aws.delete_master_key(retention_days: 7)
41
+ aws.create_master_key
42
+ end
43
+ end
44
+
45
+ describe '#generate_data_key' do
46
+ it 'creates a new data key' do
47
+ assert aws.generate_data_key('aes-128-cbc')
48
+ end
49
+ end
50
+
51
+ describe '#generate_encrypted_data_key' do
52
+ it 'creates a new data key' do
53
+ assert aws.generate_encrypted_data_key('aes-128-cbc')
54
+ end
55
+ end
56
+
57
+ describe '#encrypt' do
58
+ it 'encrypts a block of data' do
59
+ assert aws.encrypt('hello')
60
+ end
61
+ end
62
+
63
+ describe '#decrypt' do
64
+ it 'decrypts a previously encrypted block of data' do
65
+ message = 'hello world this is a top secret message'
66
+ encrypted = aws.encrypt(message)
67
+ decrypted = aws.decrypt(encrypted)
68
+ assert_equal message, decrypted
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ 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.0.1
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-05-03 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:
@@ -51,14 +51,17 @@ files:
51
51
  - lib/symmetric_encryption/header.rb
52
52
  - lib/symmetric_encryption/key.rb
53
53
  - lib/symmetric_encryption/keystore.rb
54
+ - lib/symmetric_encryption/keystore/aws.rb
54
55
  - lib/symmetric_encryption/keystore/environment.rb
55
56
  - lib/symmetric_encryption/keystore/file.rb
57
+ - lib/symmetric_encryption/keystore/heroku.rb
56
58
  - lib/symmetric_encryption/keystore/memory.rb
57
59
  - lib/symmetric_encryption/railtie.rb
58
60
  - lib/symmetric_encryption/railties/symmetric_encryption_validator.rb
59
61
  - lib/symmetric_encryption/reader.rb
60
62
  - lib/symmetric_encryption/rsa_key.rb
61
63
  - lib/symmetric_encryption/symmetric_encryption.rb
64
+ - lib/symmetric_encryption/utils/aws.rb
62
65
  - lib/symmetric_encryption/utils/re_encrypt_files.rb
63
66
  - lib/symmetric_encryption/version.rb
64
67
  - lib/symmetric_encryption/writer.rb
@@ -76,20 +79,23 @@ files:
76
79
  - test/encoder_test.rb
77
80
  - test/header_test.rb
78
81
  - test/key_test.rb
82
+ - test/keystore/aws_test.rb
79
83
  - test/keystore/environment_test.rb
80
84
  - test/keystore/file_test.rb
85
+ - test/keystore/heroku_test.rb
81
86
  - test/keystore_test.rb
82
87
  - test/mongoid_test.rb
83
88
  - test/reader_test.rb
84
89
  - test/symmetric_encryption_test.rb
85
90
  - test/test_db.sqlite3
86
91
  - test/test_helper.rb
92
+ - test/utils/aws_test.rb
87
93
  - test/writer_test.rb
88
94
  homepage: http://rocketjob.github.io/symmetric-encryption/
89
95
  licenses:
90
96
  - Apache-2.0
91
97
  metadata: {}
92
- post_install_message:
98
+ post_install_message:
93
99
  rdoc_options: []
94
100
  require_paths:
95
101
  - lib
@@ -104,25 +110,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
110
  - !ruby/object:Gem::Version
105
111
  version: '0'
106
112
  requirements: []
107
- rubyforge_project:
113
+ rubyforge_project:
108
114
  rubygems_version: 2.7.6
109
- signing_key:
115
+ signing_key:
110
116
  specification_version: 4
111
117
  summary: Encrypt ActiveRecord and Mongoid attributes, files and passwords in configuration
112
118
  files.
113
119
  test_files:
114
- - test/keystore/environment_test.rb
115
- - test/keystore/file_test.rb
116
120
  - test/symmetric_encryption_test.rb
117
- - test/config/test_secondary_1.key
118
- - test/config/mongoid.yml
119
- - test/config/test_new.iv
120
- - test/config/test_secondary_1.iv
121
- - test/config/database.yml
122
- - test/config/test_new.key
123
- - test/config/symmetric-encryption.yml
124
- - test/config/empty.csv
125
- - test/config/mongo_mapper.yml
126
121
  - test/test_db.sqlite3
127
122
  - test/mongoid_test.rb
128
123
  - test/active_record_test.rb
@@ -134,3 +129,17 @@ test_files:
134
129
  - test/test_helper.rb
135
130
  - test/writer_test.rb
136
131
  - test/cipher_test.rb
132
+ - test/keystore/environment_test.rb
133
+ - test/keystore/file_test.rb
134
+ - test/keystore/heroku_test.rb
135
+ - test/keystore/aws_test.rb
136
+ - test/config/test_secondary_1.key
137
+ - test/config/mongoid.yml
138
+ - test/config/test_new.iv
139
+ - test/config/test_secondary_1.iv
140
+ - test/config/database.yml
141
+ - test/config/test_new.key
142
+ - test/config/symmetric-encryption.yml
143
+ - test/config/empty.csv
144
+ - test/config/mongo_mapper.yml
145
+ - test/utils/aws_test.rb