symmetric-encryption 4.0.1 → 4.1.0

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