symmetric-encryption 4.1.1 → 4.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/test/reader_test.rb DELETED
@@ -1,334 +0,0 @@
1
- require_relative 'test_helper'
2
- require 'stringio'
3
-
4
- # Unit Test for SymmetricEncrypted::ReaderStream
5
- #
6
- class ReaderTest < Minitest::Test
7
- describe SymmetricEncryption::Reader do
8
- before do
9
- @data = [
10
- "Hello World\n",
11
- "Keep this secret\n",
12
- 'And keep going even further and further...'
13
- ]
14
- @data_str = @data.inject('') { |sum, str| sum << str }
15
- @data_len = @data_str.length
16
- # Use Cipher 0 since it does not always include a header
17
- @cipher = SymmetricEncryption.cipher(0)
18
- @data_encrypted_without_header = @cipher.binary_encrypt(@data_str, header: false)
19
-
20
- header = SymmetricEncryption::Header.new(
21
- version: @cipher.version,
22
- iv: @cipher.iv,
23
- key: @cipher.send(:key),
24
- cipher_name: @cipher.cipher_name
25
- )
26
- @data_encrypted_with_header = @cipher.binary_encrypt(@data_str, header: header)
27
-
28
- # Verify regular decrypt can decrypt this string
29
- @cipher.binary_decrypt(@data_encrypted_without_header)
30
- @cipher.binary_decrypt(@data_encrypted_with_header)
31
- assert @data_encrypted_without_header != @data_encrypted_with_header
32
- end
33
-
34
- [true, false].each do |header|
35
- describe header do
36
- before do
37
- @data_encrypted = header ? @data_encrypted_with_header : @data_encrypted_without_header
38
- end
39
-
40
- it '#read()' do
41
- stream = StringIO.new(@data_encrypted)
42
- # Version 0 supplied if the file/stream does not have a header
43
- decrypted = SymmetricEncryption::Reader.open(stream, version: 0, &:read)
44
- assert_equal @data_str, decrypted
45
- end
46
-
47
- it '#read(size) followed by #read()' do
48
- stream = StringIO.new(@data_encrypted)
49
- # Version 0 supplied if the file/stream does not have a header
50
- decrypted = SymmetricEncryption::Reader.open(stream, version: 0) do |file|
51
- file.read(10)
52
- file.read
53
- end
54
- assert_equal @data_str[10..-1], decrypted
55
- end
56
-
57
- it '#each_line' do
58
- stream = StringIO.new(@data_encrypted)
59
- i = 0
60
- # Version 0 supplied if the file/stream does not have a header
61
- SymmetricEncryption::Reader.open(stream, version: 0) do |file|
62
- file.each_line do |line|
63
- assert_equal @data[i], line
64
- i += 1
65
- end
66
- end
67
- end
68
-
69
- it '#read(size)' do
70
- stream = StringIO.new(@data_encrypted)
71
- # Version 0 supplied if the file/stream does not have a header
72
- SymmetricEncryption::Reader.open(stream, version: 0) do |file|
73
- index = 0
74
- [0, 10, 5, 5000].each do |size|
75
- buf = file.read(size)
76
- if size.zero?
77
- assert_equal '', buf
78
- else
79
- assert_equal @data_str[index..index + size - 1], buf
80
- end
81
- index += size
82
- end
83
- end
84
- end
85
- end
86
- end
87
-
88
- [
89
- # No Header
90
- {header: false, random_key: false, random_iv: false, compress: false},
91
- # Default Header with random key and iv
92
- {},
93
- # Header with no compression ( default anyway )
94
- {compress: false},
95
- # Compress and use Random key, iv
96
- {compress: true},
97
- # Header but not random key or iv
98
- {random_key: false},
99
- # Random iv only
100
- {random_key: false, random_iv: true},
101
- # Random iv only with compression
102
- {random_iv: true, compress: true}
103
- ].each do |options|
104
-
105
- %i[data empty blank].each do |usecase|
106
- describe "read from #{usecase} file with options: #{options.inspect}" do
107
- before do
108
- case usecase
109
- when :data
110
- # Create encrypted file
111
- @eof = false
112
- @file_name = '_test'
113
- @header = (options[:header] != false)
114
- SymmetricEncryption::Writer.open(@file_name, options) do |file|
115
- @data.inject(0) { |sum, str| sum + file.write(str) }
116
- end
117
- when :empty
118
- @data_str = ''
119
- @eof = true
120
- @file_name = '_test_empty'
121
- @header = (options[:header] != false)
122
- SymmetricEncryption::Writer.open(@file_name, options) do |file|
123
- # Leave data portion empty
124
- end
125
- when :blank
126
- @data_str = ''
127
- @eof = true
128
- @file_name = File.join(File.dirname(__FILE__), 'config/empty.csv')
129
- @header = false
130
- assert_equal 0, File.size(@file_name)
131
- else
132
- raise "Unhandled usecase: #{usecase}"
133
- end
134
- @data_size = @data_str.length
135
- end
136
-
137
- after do
138
- File.delete(@file_name) if File.exist?(@file_name) && !@file_name.end_with?('empty.csv')
139
- end
140
-
141
- it '.empty?' do
142
- assert_equal @data_size.zero?, SymmetricEncryption::Reader.empty?(@file_name)
143
- assert_raises Errno::ENOENT do
144
- SymmetricEncryption::Reader.empty?('missing_file')
145
- end
146
- end
147
-
148
- it '.header_present?' do
149
- assert_equal @header, SymmetricEncryption::Reader.header_present?(@file_name)
150
- assert_raises Errno::ENOENT do
151
- SymmetricEncryption::Reader.header_present?('missing_file')
152
- end
153
- end
154
-
155
- it '.open return Zlib::GzipReader when compressed' do
156
- file = SymmetricEncryption::Reader.open(@file_name)
157
- # assert_equal (@header && (options[:compress]||false)), file.is_a?(Zlib::GzipReader)
158
- file.close
159
- end
160
-
161
- it '#read' do
162
- data = nil
163
- eof = nil
164
- result = SymmetricEncryption::Reader.open(@file_name) do |file|
165
- eof = file.eof?
166
- data = file.read
167
- end
168
- assert_equal @eof, eof
169
- assert_equal @data_str, data
170
- assert_equal @data_str, result
171
- end
172
-
173
- it '#read(size)' do
174
- file = SymmetricEncryption::Reader.open(@file_name)
175
- eof = file.eof?
176
- data = file.read(4096)
177
- file.close
178
-
179
- assert_equal @eof, eof
180
- if @data_size.positive?
181
- assert_equal @data_str, data
182
- else
183
- assert_nil data
184
- end
185
- end
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
-
207
- it '#each_line' do
208
- SymmetricEncryption::Reader.open(@file_name) do |file|
209
- i = 0
210
- file.each_line do |line|
211
- assert_equal @data[i], line
212
- i += 1
213
- end
214
- end
215
- end
216
-
217
- it '#rewind' do
218
- decrypted = SymmetricEncryption::Reader.open(@file_name) do |file|
219
- file.read
220
- file.rewind
221
- file.read
222
- end
223
- assert_equal @data_str, decrypted
224
- end
225
-
226
- it '#gets(nil,size)' do
227
- file = SymmetricEncryption::Reader.open(@file_name)
228
- eof = file.eof?
229
- data = file.gets(nil, 4096)
230
- file.close
231
-
232
- assert_equal @eof, eof
233
- if @data_size.positive?
234
- assert_equal @data_str, data
235
- elsif defined?(JRuby)
236
- # On JRuby Zlib::GzipReader.new(file) returns '' instead of nil on an empty file
237
- assert data.blank?
238
- else
239
- assert_nil data
240
- end
241
- end
242
-
243
- it '#gets(delim)' do
244
- SymmetricEncryption::Reader.open(@file_name) do |file|
245
- i = 0
246
- while (line = file.gets("\n"))
247
- assert_equal @data[i], line
248
- i += 1
249
- end
250
- assert_equal (@data_size.positive? ? 3 : 0), i
251
- end
252
- end
253
-
254
- it '#gets(delim,size)' do
255
- SymmetricEncryption::Reader.open(@file_name) do |file|
256
- i = 0
257
- i += 1 while file.gets("\n", 128)
258
- assert_equal (@data_size.positive? ? 3 : 0), i
259
- end
260
- end
261
- end
262
- end
263
- end
264
-
265
- describe 'reading from files with previous keys' do
266
- before do
267
- @file_name = '_test'
268
- # Create encrypted file with old encryption key
269
- SymmetricEncryption::Writer.open(@file_name, version: 0) do |file|
270
- @data.inject(0) { |sum, str| sum + file.write(str) }
271
- end
272
- end
273
-
274
- after do
275
- File.delete(@file_name) if File.exist?(@file_name)
276
- end
277
-
278
- it 'decrypt from file in a single read' do
279
- decrypted = SymmetricEncryption::Reader.open(@file_name, &:read)
280
- assert_equal @data_str, decrypted
281
- end
282
-
283
- it 'decrypt from file a line at a time' do
284
- SymmetricEncryption::Reader.open(@file_name) do |file|
285
- i = 0
286
- file.each_line do |line|
287
- assert_equal @data[i], line
288
- i += 1
289
- end
290
- end
291
- end
292
-
293
- it 'support rewind' do
294
- decrypted = SymmetricEncryption::Reader.open(@file_name) do |file|
295
- file.read
296
- file.rewind
297
- file.read
298
- end
299
- assert_equal @data_str, decrypted
300
- end
301
- end
302
-
303
- describe 'reading from files with previous keys without a header' do
304
- before do
305
- @file_name = '_test'
306
- # Create encrypted file with old encryption key
307
- SymmetricEncryption::Writer.open(@file_name, version: 0, header: false, random_key: false, random_iv: false, compress: false) do |file|
308
- @data.inject(0) { |sum, str| sum + file.write(str) }
309
- end
310
- end
311
-
312
- after do
313
- begin
314
- File.delete(@file_name) if File.exist?(@file_name)
315
- rescue Errno::EACCES
316
- # Required for Windows
317
- nil
318
- end
319
- end
320
-
321
- it 'decrypt from file in a single read' do
322
- decrypted = SymmetricEncryption::Reader.open(@file_name, version: 0, &:read)
323
- assert_equal @data_str, decrypted
324
- end
325
-
326
- it 'decrypt from file in a single read with different version' do
327
- # Should fail since file was encrypted using version 0 key
328
- assert_raises OpenSSL::Cipher::CipherError do
329
- SymmetricEncryption::Reader.read(@file_name, version: 1)
330
- end
331
- end
332
- end
333
- end
334
- end
@@ -1,239 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- # Unit Test for SymmetricEncryption
4
- #
5
- class SymmetricEncryptionTest < Minitest::Test
6
- describe 'SymmetricEncryption' do
7
- describe 'configuration' do
8
- before do
9
- config = SymmetricEncryption::Config.new(
10
- file_name: File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'),
11
- env: 'test'
12
- )
13
- @ciphers = config.ciphers
14
-
15
- @cipher_v2, @cipher_v6, @cipher_v1, @cipher_v0 = @ciphers
16
- end
17
-
18
- it 'matches config file for first cipher' do
19
- cipher = SymmetricEncryption.cipher
20
- assert @cipher_v2.send(:key)
21
- assert @cipher_v2.send(:iv)
22
- assert @cipher_v2.version
23
- assert_equal @cipher_v2.cipher_name, cipher.cipher_name
24
- assert_equal @cipher_v2.version, cipher.version
25
- assert_equal false, SymmetricEncryption.secondary_ciphers.include?(cipher)
26
- end
27
-
28
- it 'match config file for v1 cipher' do
29
- cipher = SymmetricEncryption.cipher(2)
30
- assert @cipher_v2.cipher_name
31
- assert @cipher_v2.version
32
- assert_equal @cipher_v2.cipher_name, cipher.cipher_name
33
- assert_equal @cipher_v2.version, cipher.version
34
- assert_equal false, SymmetricEncryption.secondary_ciphers.include?(cipher)
35
- end
36
-
37
- it 'match config file for v0 cipher' do
38
- cipher = SymmetricEncryption.cipher(0)
39
- assert @cipher_v0.cipher_name
40
- assert @cipher_v0.version
41
- assert_equal @cipher_v0.cipher_name, cipher.cipher_name
42
- assert_equal @cipher_v0.version, cipher.version
43
- assert_equal true, SymmetricEncryption.secondary_ciphers.include?(cipher)
44
- end
45
- end
46
-
47
- %i[none base64 base64strict base16].each do |encoding|
48
- describe "encoding: #{encoding}" do
49
- before do
50
- @social_security_number = '987654321'
51
- @social_security_number_encrypted =
52
- case encoding
53
- when :base64
54
- "QEVuQwIAS+8X1NRrqdfEIQyFHVPuVA==\n"
55
- when :base64strict
56
- 'QEVuQwIAS+8X1NRrqdfEIQyFHVPuVA=='
57
- when :base16
58
- '40456e4302004bef17d4d46ba9d7c4210c851d53ee54'
59
- when :none
60
- "@EnC\x02\x00K\xEF\x17\xD4\xD4k\xA9\xD7\xC4!\f\x85\x1DS\xEET".force_encoding(Encoding.find('binary'))
61
- else
62
- raise "Add test for encoding: #{encoding}"
63
- end
64
- @non_utf8 = "\xc2".force_encoding('binary')
65
- @encoding = SymmetricEncryption.cipher.encoding
66
- SymmetricEncryption.cipher.encoding = encoding
67
- end
68
-
69
- after do
70
- SymmetricEncryption.cipher.encoding = @encoding
71
- end
72
-
73
- it 'encrypt simple string' do
74
- assert_equal @social_security_number_encrypted, SymmetricEncryption.encrypt(@social_security_number)
75
- end
76
-
77
- it 'decrypt string' do
78
- assert decrypted = SymmetricEncryption.decrypt(@social_security_number_encrypted)
79
- assert_equal @social_security_number, decrypted
80
- assert_equal Encoding.find('utf-8'), decrypted.encoding, decrypted
81
- end
82
-
83
- it 'return BINARY encoding for non-UTF-8 encrypted data' do
84
- assert_equal Encoding.find('binary'), @non_utf8.encoding
85
- assert_equal true, @non_utf8.valid_encoding?
86
- assert encrypted = SymmetricEncryption.encrypt(@non_utf8)
87
- assert decrypted = SymmetricEncryption.decrypt(encrypted)
88
- assert_equal true, decrypted.valid_encoding?
89
- assert_equal Encoding.find('binary'), decrypted.encoding, decrypted
90
- assert_equal @non_utf8, decrypted
91
- end
92
-
93
- it 'return nil when encrypting nil' do
94
- assert_nil SymmetricEncryption.encrypt(nil)
95
- end
96
-
97
- it "return '' when encrypting ''" do
98
- assert_equal '', SymmetricEncryption.encrypt('')
99
- end
100
-
101
- it 'return nil when decrypting nil' do
102
- assert_nil SymmetricEncryption.decrypt(nil)
103
- end
104
-
105
- it "return '' when decrypting ''" do
106
- assert_equal '', SymmetricEncryption.decrypt('')
107
- end
108
-
109
- it 'determine if string is encrypted' do
110
- if %i[base64strict base64].include?(encoding)
111
- assert SymmetricEncryption.encrypted?(@social_security_number_encrypted)
112
- refute SymmetricEncryption.encrypted?(@social_security_number)
113
-
114
- # Without a header it can only assume it is not encrypted
115
- refute SymmetricEncryption.encrypted?(SymmetricEncryption.encrypt(@social_security_number, header: false))
116
- end
117
- end
118
- end
119
- end
120
-
121
- describe 'using select_cipher' do
122
- before do
123
- @social_security_number = '987654321'
124
- # Encrypt data without a header and encode with base64 which has a trailing '\n'
125
- no_header = SymmetricEncryption.cipher(0).binary_encrypt(@social_security_number, header: false)
126
- @encrypted_0_ssn = SymmetricEncryption.cipher(0).encode(no_header)
127
-
128
- SymmetricEncryption.select_cipher do |encoded_str, _decoded_str|
129
- # Use cipher version 0 if the encoded string ends with "\n" otherwise
130
- # use the current default cipher
131
- encoded_str.end_with?("\n") ? SymmetricEncryption.cipher(0) : SymmetricEncryption.cipher
132
- end
133
- end
134
-
135
- after do
136
- # Clear out select_cipher
137
- SymmetricEncryption.select_cipher
138
- end
139
-
140
- it 'decrypt string without a header using an old cipher' do
141
- assert_equal @social_security_number, SymmetricEncryption.decrypt(@encrypted_0_ssn)
142
- end
143
- end
144
-
145
- describe 'without select_cipher' do
146
- before do
147
- @social_security_number = '987654321'
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)
150
- assert @encrypted_0_ssn = SymmetricEncryption.cipher(0).encode(no_header)
151
- end
152
-
153
- it 'decrypt string without a header using an old cipher' do
154
- assert_raises OpenSSL::Cipher::CipherError do
155
- SymmetricEncryption.decrypt(@encrypted_0_ssn)
156
- end
157
- end
158
- end
159
-
160
- describe 'random iv' do
161
- before do
162
- @social_security_number = '987654321'
163
- end
164
-
165
- it 'encrypt and then decrypt using random iv' do
166
- # Encrypt with random iv
167
- assert encrypted = SymmetricEncryption.encrypt(@social_security_number, random_iv: true)
168
- assert_equal @social_security_number, SymmetricEncryption.decrypt(encrypted)
169
- end
170
-
171
- it 'encrypt and then decrypt using random iv with higher version' do
172
- # Encrypt with random iv
173
- assert encrypted = SymmetricEncryption.cipher(6).encrypt(@social_security_number, random_iv: true)
174
- assert_equal @social_security_number, SymmetricEncryption.decrypt(encrypted)
175
- end
176
-
177
- it 'encrypt and then decrypt using random iv with compression' do
178
- # Encrypt with random iv and compress
179
- assert encrypted = SymmetricEncryption.encrypt(@social_security_number, random_iv: true, compress: true)
180
- assert_equal @social_security_number, SymmetricEncryption.decrypt(encrypted)
181
- end
182
- end
183
-
184
- describe 'data types' do
185
- describe 'string' do
186
- before do
187
- @social_security_number = '987654321'
188
- end
189
-
190
- it 'encrypt and decrypt value to and from a string' do
191
- assert encrypted = SymmetricEncryption.encrypt(@social_security_number, type: :string)
192
- assert_equal @social_security_number, SymmetricEncryption.decrypt(encrypted, type: :string)
193
- end
194
-
195
- it 'retains empty' do
196
- encrypted = SymmetricEncryption.encrypt('', type: :string)
197
- assert_equal '', encrypted
198
- assert_equal '', SymmetricEncryption.decrypt(encrypted, type: :string)
199
- end
200
-
201
- it 'retains nil' do
202
- assert_nil encrypted = SymmetricEncryption.encrypt(nil, type: :string)
203
- assert_nil SymmetricEncryption.decrypt(encrypted, type: :string)
204
- end
205
- end
206
-
207
- {
208
- integer: 21,
209
- float: 2.5,
210
- decimal: BigDecimal('12.58'),
211
- datetime: DateTime.new(2001, 11, 26, 20, 55, 54, '-5'),
212
- time: Time.new(2013, 1, 1, 22, 30, 0, '-04:00'),
213
- date: Date.new(1927, 4, 1),
214
- boolean: true,
215
- yaml: {a: :b},
216
- json: {'a' => 'b'}
217
- }.each_pair do |type, value|
218
- describe type.to_s do
219
- it 'encrypt and decrypt' do
220
- assert encrypted = SymmetricEncryption.encrypt(value, type: type)
221
- assert_equal value, SymmetricEncryption.decrypt(encrypted, type: type)
222
- end
223
-
224
- it 'retains nil' do
225
- assert_nil encrypted = SymmetricEncryption.encrypt(nil, type: type)
226
- assert_nil SymmetricEncryption.decrypt(encrypted, type: type)
227
- end
228
- end
229
- end
230
-
231
- describe 'boolean false' do
232
- it 'encrypt and decrypt' do
233
- assert encrypted = SymmetricEncryption.encrypt(false, type: :boolean)
234
- assert_equal false, SymmetricEncryption.decrypt(encrypted, type: :boolean)
235
- end
236
- end
237
- end
238
- end
239
- end
data/test/test_db.sqlite3 DELETED
Binary file
data/test/test_helper.rb DELETED
@@ -1,12 +0,0 @@
1
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
-
3
- require 'yaml'
4
- require 'minitest/autorun'
5
- require 'minitest/stub_any_instance'
6
- require 'awesome_print'
7
- require 'active_record'
8
- require 'symmetric-encryption'
9
- require 'fileutils'
10
-
11
- # Load Symmetric Encryption keys
12
- SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
@@ -1,74 +0,0 @@
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