ezcrypto 0.2.1 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +27 -0
- data/README +13 -1
- data/README_ACTIVE_CRYPTO +3 -2
- data/init.rb +2 -0
- data/lib/active_crypto.rb +55 -21
- data/lib/ezcrypto.rb +246 -30
- data/rakefile +6 -8
- data/test/active_crypto_test.rb +197 -0
- data/test/database.yml +18 -0
- data/test/ezcrypto_test.rb +200 -100
- data/test/test_helper.rb +36 -0
- metadata +6 -10
- data/lib/CVS/Entries +0 -3
- data/lib/CVS/Repository +0 -1
- data/lib/CVS/Root +0 -1
- data/test/CVS/Entries +0 -2
- data/test/CVS/Repository +0 -1
- data/test/CVS/Root +0 -1
data/CHANGELOG
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
0.3 February 25th, 2006 new encrypted file support by Dirk (dirk.barnikel@gmx.de) Thanks Dirk.
|
2
|
+
|
3
|
+
* Added test case for the file-related stuff. file-stuff
|
4
|
+
seems to work fine
|
5
|
+
|
6
|
+
* Replaced hard coded IO buffersize (512) with class attribute
|
7
|
+
Key#block_size and default value.
|
8
|
+
|
9
|
+
* Modification to create {De,En}crypters only via the factory methods
|
10
|
+
Key#{de,en}crypter.
|
11
|
+
|
12
|
+
* Added Key#{de,en}crypt_file methods that take a file and de- or encrypts it.
|
13
|
+
|
14
|
+
* The methods are implemented to call the cipher with small chunks of data (512 bytes) to keep memory usage low.
|
15
|
+
|
16
|
+
* By default, the original file is first overwritten and then removed.
|
17
|
+
|
18
|
+
* This overwrite is not really safe but should make it harder to restore the data of the removed file from the filesystem.
|
19
|
+
|
20
|
+
* Added Key#{store,load} methods that read and write Key data to/from files.
|
21
|
+
|
22
|
+
* Added Key#safe_{create,delete,read} methods to encapsulate the handling of files inside EzCrypto.
|
23
|
+
|
24
|
+
0.2.2 January 4th, 2006 Bug fixes and unit tests for active_crypto
|
25
|
+
|
26
|
+
There were some serious problems with ActiveCrypto's support for having keys in associated classes. I also added unit tests to active_crypto. The support code was brutaly stolen from Rick Olson's acts_as_paranoid library. Unfortunately I disabled the schema stuff for now, but will add it in the next release, which hopefully is soon.
|
27
|
+
|
1
28
|
0.2.1 November 2nd, 2005 New method in KeyHolder
|
2
29
|
|
3
30
|
Added set_encoded_key(enc) to KeyHolder for setting a key with the Base64 encoded keyvalue.
|
data/README
CHANGED
@@ -134,7 +134,19 @@ Also see my blogs at:
|
|
134
134
|
http://stakeventures.com and
|
135
135
|
http://neubia.com
|
136
136
|
|
137
|
-
This project was based on code used in my
|
137
|
+
This project was based on code used in my projects StakeItOut, WideWord and WideBlog.
|
138
|
+
|
139
|
+
StakeItOut lets you securely share web services with your partners.
|
140
|
+
|
138
141
|
https://stakeitout.com
|
139
142
|
|
143
|
+
WideWord lets you collaboratively write and share documents that remain 100% encrypted on the server. Only you have the keys:
|
144
|
+
|
145
|
+
http://wideword.net
|
146
|
+
|
147
|
+
WideBlog is a secure private blogging system designed for private project blogs. It uses the same encryption technology as WideWord and is very easy to use:
|
148
|
+
|
149
|
+
http://wideblog.net
|
150
|
+
|
151
|
+
|
140
152
|
(C) 2005 Pelle Braendgaard
|
data/README_ACTIVE_CRYPTO
CHANGED
@@ -11,7 +11,7 @@ ActiveCrypto is based on EzCrypto and provides application oriented crypto suppo
|
|
11
11
|
|
12
12
|
Download it from here:
|
13
13
|
|
14
|
-
http://rubyforge.org/frs/?group_id=755
|
14
|
+
http://rubyforge.org/frs/?group_id=755
|
15
15
|
|
16
16
|
or install it via Ruby Gems:
|
17
17
|
|
@@ -115,7 +115,8 @@ Also see my blogs at:
|
|
115
115
|
http://stakeventures.com and
|
116
116
|
http://neubia.com
|
117
117
|
|
118
|
-
This project was based on code used in my
|
118
|
+
This project was based on code used in my projects WideWord where you can securely share documents and StakeItOut, where you can securely share web services with your partners.
|
119
|
+
https://wideword.net
|
119
120
|
https://stakeitout.com
|
120
121
|
|
121
122
|
(C) 2005 Pelle Braendgaard
|
data/init.rb
ADDED
data/lib/active_crypto.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "
|
1
|
+
require "ezcrypto.rb"
|
2
2
|
module ActiveRecord # :nodoc:
|
3
3
|
module Crypto #:nodoc:
|
4
4
|
|
@@ -49,18 +49,23 @@ Include optional option :key, to specify an external KeyHolder, which holds the
|
|
49
49
|
|
50
50
|
=end
|
51
51
|
def encrypt(*attributes)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
52
|
+
include ActiveRecord::Crypto::Encrypted
|
53
|
+
alias_method :orig_write_attribute, :write_attribute
|
54
|
+
alias_method :write_attribute,:write_encrypted_attribute
|
55
|
+
options=attributes.last.is_a?(Hash) ? attributes.pop : {}
|
56
|
+
if options and options[:key]
|
57
|
+
include ActiveRecord::Crypto::AssociationKeyHolder
|
58
|
+
|
59
|
+
module_eval <<-"end;"
|
60
|
+
def session_key
|
61
|
+
(send :#{options[:key]} ).send :session_key
|
62
|
+
end
|
63
|
+
@@external_key=true
|
64
|
+
end;
|
65
|
+
else
|
66
|
+
include ActiveRecord::Crypto::KeyHolder
|
67
|
+
end
|
68
|
+
|
64
69
|
self.encrypted_attributes=attributes
|
65
70
|
for enc in attributes
|
66
71
|
|
@@ -88,7 +93,7 @@ Use it as follows:
|
|
88
93
|
|
89
94
|
=end
|
90
95
|
def keyholder()
|
91
|
-
include ActiveRecord::Crypto::
|
96
|
+
include ActiveRecord::Crypto::AssociationKeyHolder
|
92
97
|
end
|
93
98
|
|
94
99
|
=begin rdoc
|
@@ -121,7 +126,7 @@ This module handles all standard key management features.
|
|
121
126
|
Creates a key for object based on given password and an optional salt.
|
122
127
|
=end
|
123
128
|
def enter_password(password,salt="onetwothree")
|
124
|
-
set_session_key(EzCrypto::Key.with_password
|
129
|
+
set_session_key(EzCrypto::Key.with_password(password, salt))
|
125
130
|
end
|
126
131
|
|
127
132
|
=begin rdoc
|
@@ -134,25 +139,46 @@ Decodes the Base64 encoded key and uses it as it's session key
|
|
134
139
|
Sets a session key for the object. This should be a EzCrypto::Key instance.
|
135
140
|
=end
|
136
141
|
def set_session_key(key)
|
137
|
-
|
142
|
+
@session_key=key
|
138
143
|
end
|
139
144
|
|
140
145
|
=begin rdoc
|
141
146
|
Returns the session_key
|
142
147
|
=end
|
143
148
|
def session_key
|
144
|
-
|
149
|
+
@session_key
|
145
150
|
end
|
146
151
|
|
152
|
+
end
|
153
|
+
|
154
|
+
module AssociationKeyHolder
|
155
|
+
include KeyHolder
|
156
|
+
=begin rdoc
|
157
|
+
Sets a session key for the object. This should be a EzCrypto::Key instance.
|
158
|
+
=end
|
159
|
+
def set_session_key(key)
|
160
|
+
Base.session_keys[session_key_id]=key
|
161
|
+
end
|
162
|
+
|
163
|
+
=begin rdoc
|
164
|
+
Returns the session_key
|
165
|
+
=end
|
166
|
+
def session_key
|
167
|
+
if session_key_id
|
168
|
+
Base.session_keys[session_key_id]
|
169
|
+
else
|
170
|
+
nil
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
147
174
|
private
|
148
|
-
|
175
|
+
|
149
176
|
def session_key_id
|
150
177
|
"#{self.class.to_s}:#{id}"
|
151
178
|
end
|
152
179
|
end
|
153
180
|
|
154
181
|
module Encrypted #:nodoc:
|
155
|
-
include ActiveRecord::Crypto::KeyHolder
|
156
182
|
def self.append_features(base) #:nodoc:
|
157
183
|
super
|
158
184
|
base.module_eval <<-"end;"
|
@@ -182,7 +208,11 @@ Returns the session_key
|
|
182
208
|
if session_key.nil?
|
183
209
|
raise MissingKeyError
|
184
210
|
else
|
185
|
-
|
211
|
+
if data
|
212
|
+
session_key.decrypt(data)
|
213
|
+
else
|
214
|
+
nil
|
215
|
+
end
|
186
216
|
end
|
187
217
|
end
|
188
218
|
|
@@ -190,7 +220,11 @@ Returns the session_key
|
|
190
220
|
if session_key.nil?
|
191
221
|
raise MissingKeyError
|
192
222
|
else
|
193
|
-
|
223
|
+
if data
|
224
|
+
session_key.encrypt(data)
|
225
|
+
else
|
226
|
+
nil
|
227
|
+
end
|
194
228
|
end
|
195
229
|
end
|
196
230
|
|
data/lib/ezcrypto.rb
CHANGED
@@ -41,8 +41,26 @@ https://stakeitout.com
|
|
41
41
|
=end
|
42
42
|
|
43
43
|
class Key
|
44
|
-
|
45
|
-
|
44
|
+
|
45
|
+
attr_reader :raw, :algorithm
|
46
|
+
|
47
|
+
@@block_size = 512
|
48
|
+
|
49
|
+
=begin rdoc
|
50
|
+
Set the block-size for IO-operations (default: 512 bytes)
|
51
|
+
=end
|
52
|
+
def self.block_size=(size)
|
53
|
+
@@block_size = size
|
54
|
+
end
|
55
|
+
|
56
|
+
=begin rdoc
|
57
|
+
Return the block-size for IO-operations.
|
58
|
+
=end
|
59
|
+
def self.block_size
|
60
|
+
@@block_size
|
61
|
+
end
|
62
|
+
|
63
|
+
|
46
64
|
=begin rdoc
|
47
65
|
Initialize the key with raw unencoded binary key data. This needs to be at least
|
48
66
|
16 bytes long for the default aes-128 algorithm.
|
@@ -51,28 +69,28 @@ Initialize the key with raw unencoded binary key data. This needs to be at least
|
|
51
69
|
@raw=raw
|
52
70
|
@algorithm=options[:algorithm]||"aes-128-cbc"
|
53
71
|
end
|
54
|
-
|
72
|
+
|
55
73
|
=begin rdoc
|
56
74
|
Generate random key.
|
57
75
|
=end
|
58
|
-
def self.generate(options = {})
|
76
|
+
def self.generate(options = {})
|
59
77
|
Key.new(EzCrypto::Digester.generate_key(calculate_key_size(options[:algorithm])),options)
|
60
78
|
end
|
61
|
-
|
79
|
+
|
62
80
|
=begin rdoc
|
63
|
-
Create key generated from the given password and salt
|
81
|
+
Create key generated from the given password and salt
|
64
82
|
=end
|
65
83
|
def self.with_password(password,salt,options = {})
|
66
84
|
Key.new(EzCrypto::Digester.get_key(password,salt,calculate_key_size(options[:algorithm])),options)
|
67
85
|
end
|
68
|
-
|
86
|
+
|
69
87
|
=begin rdoc
|
70
88
|
Initialize the key with Base64 encoded key data.
|
71
89
|
=end
|
72
90
|
def self.decode(encoded,options = {})
|
73
91
|
Key.new(Base64.decode64(encoded),options)
|
74
92
|
end
|
75
|
-
|
93
|
+
|
76
94
|
=begin rdoc
|
77
95
|
Encrypts the data with the given password and a salt. Short hand for:
|
78
96
|
|
@@ -84,30 +102,31 @@ Encrypts the data with the given password and a salt. Short hand for:
|
|
84
102
|
key=Key.with_password(password,salt,options)
|
85
103
|
key.encrypt(data)
|
86
104
|
end
|
87
|
-
|
105
|
+
|
88
106
|
=begin rdoc
|
89
107
|
Decrypts the data with the given password and a salt. Short hand for:
|
90
108
|
|
91
109
|
key=Key.with_password(password,salt,options)
|
92
110
|
key.decrypt(data)
|
93
111
|
|
94
|
-
|
112
|
+
|
95
113
|
=end
|
96
114
|
def self.decrypt_with_password(password,salt,data,options = {})
|
97
115
|
key=Key.with_password(password,salt,options)
|
98
116
|
key.decrypt(data)
|
99
117
|
end
|
100
|
-
|
118
|
+
|
101
119
|
=begin rdoc
|
102
|
-
Given an algorithm this calculates the keysize. This is used by both
|
120
|
+
Given an algorithm this calculates the keysize. This is used by both
|
121
|
+
the generate and with_password methods. This is not yet 100% complete.
|
103
122
|
=end
|
104
|
-
def self.calculate_key_size(algorithm)
|
123
|
+
def self.calculate_key_size(algorithm)
|
105
124
|
if !algorithm.nil?
|
106
125
|
algorithm=~/^([[:alnum:]]+)(-(\d+))?/
|
107
126
|
if $3
|
108
127
|
size=($3.to_i)/8
|
109
|
-
else
|
110
|
-
case $1
|
128
|
+
else
|
129
|
+
case $1
|
111
130
|
when "bf"
|
112
131
|
size = 16
|
113
132
|
when "blowfish"
|
@@ -126,7 +145,7 @@ Given an algorithm this calculates the keysize. This is used by both the generat
|
|
126
145
|
size = 16
|
127
146
|
when "rc4"
|
128
147
|
size = 16
|
129
|
-
else
|
148
|
+
else
|
130
149
|
size = 16
|
131
150
|
end
|
132
151
|
end
|
@@ -134,7 +153,7 @@ Given an algorithm this calculates the keysize. This is used by both the generat
|
|
134
153
|
if size.nil?
|
135
154
|
size = 16
|
136
155
|
end
|
137
|
-
|
156
|
+
|
138
157
|
size
|
139
158
|
end
|
140
159
|
|
@@ -144,20 +163,24 @@ returns the Base64 encoded key.
|
|
144
163
|
def encode
|
145
164
|
Base64.encode64 @raw
|
146
165
|
end
|
147
|
-
|
166
|
+
|
148
167
|
=begin rdoc
|
149
|
-
returns the Base64 encoded key. Synonym for encode.
|
168
|
+
returns the Base64 encoded key. Synonym for encode.
|
150
169
|
=end
|
151
170
|
def to_s
|
152
171
|
encode
|
153
172
|
end
|
154
|
-
|
173
|
+
|
155
174
|
=begin rdoc
|
156
175
|
Encrypts the data and returns it in encrypted binary form.
|
157
176
|
=end
|
158
177
|
def encrypt(data)
|
159
|
-
|
160
|
-
|
178
|
+
if data==nil || data==""
|
179
|
+
nil
|
180
|
+
else
|
181
|
+
encrypter("")
|
182
|
+
@cipher.encrypt(data)
|
183
|
+
end
|
161
184
|
end
|
162
185
|
|
163
186
|
=begin rdoc
|
@@ -166,27 +189,215 @@ Encrypts the data and returns it in encrypted Base64 encoded form.
|
|
166
189
|
def encrypt64(data)
|
167
190
|
Base64.encode64(encrypt(data))
|
168
191
|
end
|
169
|
-
|
192
|
+
|
170
193
|
=begin rdoc
|
171
194
|
Decrypts the data passed to it in binary format.
|
172
|
-
=end
|
195
|
+
=end
|
173
196
|
def decrypt(data)
|
174
|
-
|
175
|
-
|
197
|
+
if data==nil || data==""
|
198
|
+
nil
|
199
|
+
else
|
200
|
+
decrypter("")
|
201
|
+
@cipher.gulp(data)
|
202
|
+
end
|
176
203
|
rescue
|
177
204
|
puts @algorithm
|
178
205
|
throw $!
|
179
206
|
end
|
180
|
-
|
207
|
+
|
181
208
|
=begin rdoc
|
182
|
-
Decrypts a Base64 formatted string
|
209
|
+
Decrypts a Base64 formatted string
|
183
210
|
=end
|
184
211
|
def decrypt64(data)
|
185
212
|
decrypt(Base64.decode64(data))
|
186
213
|
end
|
187
214
|
|
215
|
+
|
216
|
+
=begin rdoc
|
217
|
+
Create a file with minimal permissions, and yield
|
218
|
+
it to a block. By default only the owner may read it.
|
219
|
+
=end
|
220
|
+
def safe_create(file, mod=0400, mask=0066)
|
221
|
+
begin
|
222
|
+
old_umask = File.umask
|
223
|
+
File.umask(mask)
|
224
|
+
File.open(file, File::CREAT | File::EXCL | File::WRONLY) do |f|
|
225
|
+
yield(f) if block_given?
|
226
|
+
end
|
227
|
+
ensure
|
228
|
+
File.umask(old_umask)
|
229
|
+
end
|
230
|
+
File.chmod(mod, file) if File.exists?(file)
|
231
|
+
File.size(file)
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
=begin rdoc
|
236
|
+
Overwrite a file with zero values before removing it's filesystem inode.
|
237
|
+
This is not very safe :-)
|
238
|
+
=end
|
239
|
+
def safe_delete(file)
|
240
|
+
begin
|
241
|
+
to_clear = File.size(file)
|
242
|
+
zeroes = Array.new(Key.block_size, "\0").join
|
243
|
+
File.chmod(0600, file)
|
244
|
+
File.open(file, File::WRONLY) do |f|
|
245
|
+
f.rewind
|
246
|
+
while to_clear > 0
|
247
|
+
f.write(zeroes)
|
248
|
+
to_clear -= Key.block_size
|
249
|
+
end
|
250
|
+
f.flush
|
251
|
+
end
|
252
|
+
ensure
|
253
|
+
File.delete(file) if File.exists?(file)
|
254
|
+
end
|
255
|
+
return !File.exists?(file)
|
256
|
+
end
|
257
|
+
|
258
|
+
|
259
|
+
=begin rdoc
|
260
|
+
Open a file readonly and yield it to a block.
|
261
|
+
=end
|
262
|
+
def safe_read(file)
|
263
|
+
File.open(file, File::RDONLY) do |i|
|
264
|
+
yield(i) if block_given?
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
private :safe_create, :safe_read, :safe_delete
|
269
|
+
|
270
|
+
=begin rdoc
|
271
|
+
Load a key from a yaml_file generated via Key#store.
|
272
|
+
=end
|
273
|
+
def self.load(filename)
|
274
|
+
require 'yaml'
|
275
|
+
hash = YAML::load_file(filename)
|
276
|
+
req = proc { |k| hash[k] or raise "Missing element #{k} in #{filename}" }
|
277
|
+
key = self.new Base64.decode64(req.call(:key)) , :algorithm => req.call(:algorithm)
|
278
|
+
return key
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
=begin rdoc
|
283
|
+
Save the key data into a file, try to do this in a secure manner.
|
284
|
+
NOTE: YAML::store & friends are not used to encance control over
|
285
|
+
the generated file format.
|
286
|
+
=end
|
287
|
+
def store(filename)
|
288
|
+
safe_create(filename) do |f|
|
289
|
+
selfenc = self.encode
|
290
|
+
f.puts "---"
|
291
|
+
f.puts ":EZCRYPTO KEY FILE: KEEP THIS SECURE !"
|
292
|
+
f.puts ":created: #{Time.now}"
|
293
|
+
f.puts ":algorithm: #{@algorithm}"
|
294
|
+
f.puts ":key: #{selfenc}"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
=begin rdoc
|
300
|
+
Get a Encrypter object. You have to call #final on it by yourself!
|
301
|
+
=end
|
302
|
+
def encrypter(target='')
|
303
|
+
@cipher = EzCrypto::Encrypter.new(self,target,@algorithm)
|
304
|
+
end
|
305
|
+
|
306
|
+
|
307
|
+
=begin rdoc
|
308
|
+
Get a Decrypter object. You have to call #final on it by yourself!
|
309
|
+
=end
|
310
|
+
def decrypter(target='')
|
311
|
+
@cipher = EzCrypto::Decrypter.new(self,target,@algorithm)
|
312
|
+
end
|
313
|
+
|
314
|
+
=begin rdoc
|
315
|
+
Create a Decrypter object and yield it to a block.
|
316
|
+
You must *not* call #final by yourself, the method
|
317
|
+
does this.
|
318
|
+
=end
|
319
|
+
def on_decrypter(target='', &block)
|
320
|
+
decrypter(target)
|
321
|
+
on_cipher(&block)
|
322
|
+
end
|
323
|
+
|
324
|
+
=begin rdoc
|
325
|
+
Create an Encrypter object and yield it to a block.
|
326
|
+
You must *not* call #final by yourself, the method
|
327
|
+
does this.
|
328
|
+
=end
|
329
|
+
def on_encrypter(target='', &block)
|
330
|
+
encrypter(target)
|
331
|
+
on_cipher(&block)
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
=begin rdoc
|
336
|
+
Helper method, yields the current cipher to a block.
|
337
|
+
=end
|
338
|
+
def on_cipher(&block)
|
339
|
+
begin
|
340
|
+
block.call @cipher
|
341
|
+
ensure
|
342
|
+
@cipher.final
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
private :on_cipher
|
347
|
+
|
348
|
+
|
349
|
+
=begin rdoc
|
350
|
+
Encrypt a file 'inplace' and add a suffix
|
351
|
+
see #cipher_file.
|
352
|
+
IMPORTANT: The inputfile will be deleted by default.
|
353
|
+
=end
|
354
|
+
def encrypt_file(src, tgt=nil, options = {} )
|
355
|
+
options = { :suffix => '.ez', :autoclean => 'true' }.update(options)
|
356
|
+
tgt = "#{src}#{options[:suffix]}" unless tgt
|
357
|
+
cipher_file :on_encrypter, src, tgt, options[:autoclean]
|
358
|
+
end
|
359
|
+
|
360
|
+
|
361
|
+
=begin rdoc
|
362
|
+
Decrypt a file 'inplace' and remove a suffix
|
363
|
+
see #cipher_file
|
364
|
+
IMPORTANT: The inputfile will be deleted by default.
|
365
|
+
=end
|
366
|
+
def decrypt_file(src, tgt=nil, options = {} )
|
367
|
+
options = { :suffix => '.ez', :autoclean => 'true' }.update(options)
|
368
|
+
unless tgt
|
369
|
+
tgt = src
|
370
|
+
tgt = tgt.gsub(/#{options[:suffix]}$/, '')
|
371
|
+
end
|
372
|
+
cipher_file :on_decrypter, src, tgt, options[:autoclean]
|
373
|
+
end
|
374
|
+
|
375
|
+
|
376
|
+
=begin rdoc
|
377
|
+
uses either #on_decrypter or #on_encrypter to transform a given sourcefile
|
378
|
+
to a targetfile. the sourcefile is deleted after sucessful transformation
|
379
|
+
the delete_source is 'true'.
|
380
|
+
=end
|
381
|
+
def cipher_file(method, sourcefile, targetfile, delete_source)
|
382
|
+
raise(ArgumentError, "source == target #{sourcefile}") if sourcefile == targetfile
|
383
|
+
safe_create(targetfile,0600) do |o|
|
384
|
+
self.send(method, o) do |c|
|
385
|
+
safe_read(sourcefile) do |i|
|
386
|
+
loop do
|
387
|
+
buffer = i.read(Key.block_size) or break
|
388
|
+
c << buffer
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
safe_delete(sourcefile) if delete_source && File.exists?(targetfile)
|
394
|
+
return targetfile
|
395
|
+
end
|
396
|
+
|
397
|
+
private :cipher_file
|
188
398
|
|
189
399
|
end
|
400
|
+
|
190
401
|
=begin rdoc
|
191
402
|
Abstract Wrapper around OpenSSL's Cipher object. Extended by Encrypter and Decrypter.
|
192
403
|
|
@@ -213,12 +424,17 @@ Warning! The interface may change.
|
|
213
424
|
@finished=false
|
214
425
|
end
|
215
426
|
|
427
|
+
|
428
|
+
def to_target(data)
|
429
|
+
return data
|
430
|
+
end
|
431
|
+
|
216
432
|
=begin rdoc
|
217
433
|
Process the givend data with the cipher.
|
218
434
|
=end
|
219
435
|
def update(data)
|
220
436
|
reset if @finished
|
221
|
-
@target<< @cipher.update(data)
|
437
|
+
@target<< to_target(@cipher.update(data))
|
222
438
|
end
|
223
439
|
|
224
440
|
=begin rdoc
|
@@ -232,7 +448,7 @@ Process the givend data with the cipher.
|
|
232
448
|
Finishes up any last bits of data in the cipher and returns the final result.
|
233
449
|
=end
|
234
450
|
def final
|
235
|
-
@target<< @cipher.final
|
451
|
+
@target<< to_target(@cipher.final)
|
236
452
|
@finished=true
|
237
453
|
@target
|
238
454
|
end
|
data/rakefile
CHANGED
@@ -8,7 +8,7 @@ require 'rake/contrib/rubyforgepublisher'
|
|
8
8
|
|
9
9
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
10
10
|
PKG_NAME = 'ezcrypto'
|
11
|
-
PKG_VERSION = '0.
|
11
|
+
PKG_VERSION = '0.3' + PKG_BUILD
|
12
12
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
13
13
|
|
14
14
|
RELEASE_NAME = "REL #{PKG_VERSION}"
|
@@ -31,14 +31,12 @@ Rake::TestTask.new { |t|
|
|
31
31
|
Rake::RDocTask.new { |rdoc|
|
32
32
|
rdoc.rdoc_dir = 'doc'
|
33
33
|
rdoc.title = "EzCrypto - Simplified Crypto Library"
|
34
|
-
rdoc.options << '--line-numbers --inline-source --main README
|
34
|
+
# rdoc.options << '--line-numbers --inline-source --main README #--template=jamis'
|
35
35
|
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
36
36
|
rdoc.rdoc_files.include('README')
|
37
37
|
rdoc.rdoc_files.include('README_ACTIVE_CRYPTO')
|
38
38
|
rdoc.rdoc_files.include('CHANGELOG')
|
39
|
-
rdoc.rdoc_files.include('lib
|
40
|
-
rdoc.rdoc_files.include('lib/active_crypto.rb')
|
41
|
-
# rdoc.rdoc_files.include('lib/ezcrypto/*.rb')
|
39
|
+
rdoc.rdoc_files.include('lib/*.rb')
|
42
40
|
}
|
43
41
|
|
44
42
|
|
@@ -60,9 +58,9 @@ spec = Gem::Specification.new do |s|
|
|
60
58
|
s.requirements << 'none'
|
61
59
|
s.require_path = 'lib'
|
62
60
|
|
63
|
-
s.files = [ "rakefile", "README", "README_ACTIVE_CRYPTO", "MIT-LICENSE","CHANGELOG" ]
|
64
|
-
s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "
|
65
|
-
s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "
|
61
|
+
s.files = [ "rakefile", "README", "README_ACTIVE_CRYPTO", "MIT-LICENSE","CHANGELOG","init.rb" ]
|
62
|
+
s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "CVS" )||item.include?("\.DS_Store")||item.include?("/\._") }
|
63
|
+
s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "CVS" )||item.include?("\.DS_Store")||item.include?("/\._") }
|
66
64
|
end
|
67
65
|
|
68
66
|
Rake::GemPackageTask.new(spec) do |p|
|
@@ -0,0 +1,197 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + "/../lib/")
|
2
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
3
|
+
require 'test/unit'
|
4
|
+
require 'active_crypto'
|
5
|
+
|
6
|
+
class User < ActiveRecord::Base
|
7
|
+
has_many :secrets
|
8
|
+
has_many :groups
|
9
|
+
keyholder
|
10
|
+
end
|
11
|
+
|
12
|
+
class Secret < ActiveRecord::Base
|
13
|
+
encrypt :name,:email, :key=>:user
|
14
|
+
belongs_to :user
|
15
|
+
has_many :children
|
16
|
+
end
|
17
|
+
|
18
|
+
class Child < ActiveRecord::Base
|
19
|
+
encrypt :email, :key=>:secret
|
20
|
+
belongs_to :secret
|
21
|
+
end
|
22
|
+
|
23
|
+
class Asset<ActiveRecord::Base
|
24
|
+
encrypt :title
|
25
|
+
has_many :caps,:dependent=>:destroy
|
26
|
+
|
27
|
+
def self.create(title,email)
|
28
|
+
asset=Asset.new
|
29
|
+
asset.set_session_key(EzCrypto::Key.generate)
|
30
|
+
asset.title=title
|
31
|
+
if asset.save
|
32
|
+
asset.share(email)
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def share(email=nil)
|
39
|
+
Cap.create_for_asset(self,email)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
class Cap < ActiveRecord::Base
|
45
|
+
belongs_to :asset
|
46
|
+
encrypt :shared_key
|
47
|
+
|
48
|
+
def self.find_by_key(cap_key)
|
49
|
+
cap_key.chop
|
50
|
+
hash=Digest::SHA1.hexdigest(cap_key)
|
51
|
+
if (cap_key.length>=20) # Sanity check
|
52
|
+
cap=self.find_by_key_hash(hash)
|
53
|
+
if cap
|
54
|
+
cap.set_encoded_key(cap_key)
|
55
|
+
cap.asset.set_encoded_key(cap.shared_key)
|
56
|
+
cap
|
57
|
+
end
|
58
|
+
else
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.create_for_asset(asset,email=nil)
|
64
|
+
cap=Cap.new
|
65
|
+
cap.email=email if email
|
66
|
+
cap.asset=asset
|
67
|
+
if cap.save
|
68
|
+
cap.set_session_key(EzCrypto::Key.generate)
|
69
|
+
cap_key=cap.session_key.encode
|
70
|
+
cap.key_hash=Digest::SHA1.hexdigest(cap_key)
|
71
|
+
cap.shared_key=asset.session_key.encode
|
72
|
+
cap.save
|
73
|
+
cap_key
|
74
|
+
else
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
class Group < ActiveRecord::Base
|
82
|
+
belongs_to :user
|
83
|
+
has_many :group_secrets
|
84
|
+
|
85
|
+
encrypt :name,:group_key, :key=>:user
|
86
|
+
end
|
87
|
+
|
88
|
+
class GroupSecret < ActiveRecord::Base
|
89
|
+
belongs_to :group
|
90
|
+
|
91
|
+
encrypt :title,:body, :key=>:group
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
class ActiveCryptoTest < Test::Unit::TestCase
|
96
|
+
|
97
|
+
def setup
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_key_holder
|
101
|
+
user=User.new
|
102
|
+
user.name="bob"
|
103
|
+
user.save
|
104
|
+
assert user.kind_of?(ActiveRecord::Crypto::KeyHolder)
|
105
|
+
assert user.kind_of?(ActiveRecord::Base)
|
106
|
+
assert user.kind_of?(User)
|
107
|
+
assert_nil user.session_key
|
108
|
+
user.enter_password "shhcccc"
|
109
|
+
assert_not_nil user.session_key
|
110
|
+
assert_not_nil user.session_key.encrypt("test")
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_encrypted_child
|
114
|
+
user=User.new
|
115
|
+
user.save
|
116
|
+
assert_nil user.session_key
|
117
|
+
user.enter_password "shhcccc"
|
118
|
+
assert_not_nil user.session_key
|
119
|
+
assert user.kind_of?(ActiveRecord::Crypto::KeyHolder)
|
120
|
+
assert user.kind_of?(ActiveRecord::Base)
|
121
|
+
assert user.kind_of?(User)
|
122
|
+
|
123
|
+
jill=user.secrets.create
|
124
|
+
|
125
|
+
assert_not_nil jill
|
126
|
+
assert jill.kind_of?(ActiveRecord::Crypto::AssociationKeyHolder)
|
127
|
+
assert jill.kind_of?(ActiveRecord::Crypto::KeyHolder)
|
128
|
+
assert jill.kind_of?(ActiveRecord::Crypto::Encrypted)
|
129
|
+
assert jill.kind_of?(ActiveRecord::Base)
|
130
|
+
assert jill.kind_of?(Secret)
|
131
|
+
|
132
|
+
assert jill.respond_to?(:session_key)
|
133
|
+
|
134
|
+
assert_not_nil jill.user
|
135
|
+
assert_not_nil jill.user.session_key
|
136
|
+
|
137
|
+
|
138
|
+
assert_not_nil jill.session_key
|
139
|
+
assert_equal user.session_key,jill.session_key
|
140
|
+
|
141
|
+
jill.name="jill"
|
142
|
+
jill.save
|
143
|
+
|
144
|
+
|
145
|
+
assert_equal "jill",jill.name
|
146
|
+
|
147
|
+
jill=user.secrets.first
|
148
|
+
assert_not_nil jill.session_key
|
149
|
+
assert_equal user.session_key,jill.session_key
|
150
|
+
assert_equal "jill",jill.name
|
151
|
+
|
152
|
+
child=jill.children.create
|
153
|
+
child.email="pelle@neubia.com"
|
154
|
+
child.save
|
155
|
+
|
156
|
+
assert_not_nil child.secret
|
157
|
+
assert_not_nil child.secret.session_key
|
158
|
+
|
159
|
+
|
160
|
+
assert_not_nil child.session_key
|
161
|
+
assert_equal user.session_key,child.session_key
|
162
|
+
|
163
|
+
assert_equal "pelle@neubia.com",child.email
|
164
|
+
|
165
|
+
child=jill.children.first
|
166
|
+
|
167
|
+
assert_not_nil child.secret
|
168
|
+
assert_not_nil child.secret.session_key
|
169
|
+
|
170
|
+
|
171
|
+
assert_not_nil child.session_key
|
172
|
+
assert_equal user.session_key,child.session_key
|
173
|
+
|
174
|
+
assert_equal "pelle@neubia.com",child.email
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_caps
|
179
|
+
key=Asset.create("title","pelle@neubia.com")
|
180
|
+
assert_not_nil key
|
181
|
+
cap=Cap.find_by_key key
|
182
|
+
assert_not_nil cap
|
183
|
+
assert_not_nil cap.asset
|
184
|
+
assert_equal "title",cap.asset.title
|
185
|
+
assert_equal "pelle@neubia.com",cap.email
|
186
|
+
|
187
|
+
bob_key=cap.asset.share("bob@bob.com")
|
188
|
+
bob_cap=Cap.find_by_key bob_key
|
189
|
+
|
190
|
+
assert_not_equal key,bob_key
|
191
|
+
assert_not_nil bob_cap
|
192
|
+
assert_not_nil bob_cap.asset
|
193
|
+
assert_equal "title",bob_cap.asset.title
|
194
|
+
assert_equal "bob@bob.com",bob_cap.email
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
data/test/database.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
sqlite:
|
2
|
+
:adapter: sqlite
|
3
|
+
:dbfile: crypto_test.sqlite.db
|
4
|
+
sqlite3:
|
5
|
+
:adapter: sqlite3
|
6
|
+
:dbfile: crypto_test.sqlite3.db
|
7
|
+
postgresql:
|
8
|
+
:adapter: postgresql
|
9
|
+
:username: postgres
|
10
|
+
:password: postgres
|
11
|
+
:database: crypto_test
|
12
|
+
:min_messages: ERROR
|
13
|
+
mysql:
|
14
|
+
:adapter: mysql
|
15
|
+
:host: localhost
|
16
|
+
:username: rails
|
17
|
+
:password:
|
18
|
+
:database: crypto_test
|
data/test/ezcrypto_test.rb
CHANGED
@@ -1,112 +1,212 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__) + "/../lib/")
|
2
2
|
|
3
3
|
require 'test/unit'
|
4
|
+
require 'fileutils'
|
4
5
|
require 'ezcrypto'
|
5
|
-
require 'base64'
|
6
|
+
require 'base64'
|
6
7
|
|
7
8
|
class EzCryptoTest < Test::Unit::TestCase
|
8
9
|
|
9
10
|
def setup
|
10
11
|
end
|
11
|
-
|
12
|
-
def test_generate_alg_key
|
13
|
-
assert_generate_alg_key "aes-128-cbc",16
|
14
|
-
assert_generate_alg_key "aes-192-cbc",24
|
15
|
-
assert_generate_alg_key "aes-256-cbc",32
|
16
|
-
assert_generate_alg_key "rc2-40-cbc",5
|
17
|
-
assert_generate_alg_key "rc2-64-cbc",8
|
18
|
-
assert_generate_alg_key "rc4-64" ,8
|
19
|
-
assert_generate_alg_key "blowfish" ,16
|
20
|
-
assert_generate_alg_key "des" ,8
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_with_password
|
24
|
-
assert_with_password "","secret","aes-128-cbc",16
|
25
|
-
assert_with_password "test","secret","aes-128-cbc",16
|
26
|
-
assert_with_password "password","secret","aes-128-cbc",16
|
27
|
-
assert_with_password "a�sldfad8q5�34j2�l4j24l6j2456","secret","aes-128-cbc",16
|
28
|
-
|
29
|
-
assert_with_password "","secret","aes-192-cbc",24
|
30
|
-
assert_with_password "test","secret","aes-192-cbc",24
|
31
|
-
assert_with_password "password","secret","aes-192-cbc",24
|
32
|
-
assert_with_password "a�sldfad8q5�34j2�l4j24l6j2456","secret","aes-192-cbc",24
|
33
|
-
|
34
|
-
assert_with_password "","secret","aes-256-cbc",32
|
35
|
-
assert_with_password "test","secret","aes-256-cbc",32
|
36
|
-
assert_with_password "password","secret","aes-256-cbc",32
|
37
|
-
assert_with_password "a�sldfad8q5�34j2�l4j24l6j2456","secret","aes-256-cbc",32
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_encoded
|
42
|
-
0.upto 32 do |size|
|
43
|
-
assert_encoded_keys size
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_encrypt
|
48
|
-
0.upto(CLEAR_TEXT.size-1) do |size|
|
49
|
-
assert_encrypt CLEAR_TEXT[0..size]
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_decrypt
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
key=EzCrypto::Key.generate :algorithm=>
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
assert_equal key.raw,
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
12
|
+
|
13
|
+
def test_generate_alg_key
|
14
|
+
assert_generate_alg_key "aes-128-cbc",16
|
15
|
+
assert_generate_alg_key "aes-192-cbc",24
|
16
|
+
assert_generate_alg_key "aes-256-cbc",32
|
17
|
+
assert_generate_alg_key "rc2-40-cbc",5
|
18
|
+
assert_generate_alg_key "rc2-64-cbc",8
|
19
|
+
assert_generate_alg_key "rc4-64" ,8
|
20
|
+
assert_generate_alg_key "blowfish" ,16
|
21
|
+
assert_generate_alg_key "des" ,8
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_with_password
|
25
|
+
assert_with_password "","secret","aes-128-cbc",16
|
26
|
+
assert_with_password "test","secret","aes-128-cbc",16
|
27
|
+
assert_with_password "password","secret","aes-128-cbc",16
|
28
|
+
assert_with_password "a�sldfad8q5�34j2�l4j24l6j2456","secret","aes-128-cbc",16
|
29
|
+
|
30
|
+
assert_with_password "","secret","aes-192-cbc",24
|
31
|
+
assert_with_password "test","secret","aes-192-cbc",24
|
32
|
+
assert_with_password "password","secret","aes-192-cbc",24
|
33
|
+
assert_with_password "a�sldfad8q5�34j2�l4j24l6j2456","secret","aes-192-cbc",24
|
34
|
+
|
35
|
+
assert_with_password "","secret","aes-256-cbc",32
|
36
|
+
assert_with_password "test","secret","aes-256-cbc",32
|
37
|
+
assert_with_password "password","secret","aes-256-cbc",32
|
38
|
+
assert_with_password "a�sldfad8q5�34j2�l4j24l6j2456","secret","aes-256-cbc",32
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_encoded
|
43
|
+
0.upto 32 do |size|
|
44
|
+
assert_encoded_keys size
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_encrypt
|
49
|
+
0.upto(CLEAR_TEXT.size-1) do |size|
|
50
|
+
assert_encrypt CLEAR_TEXT[0..size]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_decrypt
|
55
|
+
0.upto(CLEAR_TEXT.size) do |size|
|
56
|
+
assert_decrypt CLEAR_TEXT[0..size]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_decrypt64
|
61
|
+
0.upto(CLEAR_TEXT.size) do |size|
|
62
|
+
assert_decrypt64 CLEAR_TEXT[0..size]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_keyfile_store_load
|
67
|
+
|
68
|
+
algo, size = "aes-256-cbc", 32
|
69
|
+
keyfile = 'ezcrypto-test.key'
|
70
|
+
|
71
|
+
FileUtils.rm [keyfile], :force => true
|
72
|
+
key = EzCrypto::Key.generate :algorithm => algo
|
73
|
+
assert_file_not_exists keyfile
|
74
|
+
key.store keyfile
|
75
|
+
assert_file_exists keyfile
|
76
|
+
assert_file_permissions keyfile, 0100400
|
77
|
+
|
78
|
+
key2 = EzCrypto::Key.load(keyfile)
|
79
|
+
assert_equal key.raw, key2.raw
|
80
|
+
|
81
|
+
FileUtils.rm [keyfile], :force => true
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_filestuff_with_defaults
|
85
|
+
|
86
|
+
clearfile = 'lorem_ipsum.txt'
|
87
|
+
keyfile = 'lorem_ipsum.key'
|
88
|
+
algo, size = "aes-256-cbc", 32
|
89
|
+
|
90
|
+
File.open(clearfile, 'w') { |f| f.write(CLEAR_TEXT) }
|
91
|
+
assert_file_contains clearfile, CLEAR_TEXT
|
92
|
+
|
93
|
+
key = EzCrypto::Key.generate :algorithm => algo
|
94
|
+
|
95
|
+
# default behaviour: remove clearfile, append '.ez' suffix
|
96
|
+
cryptfile = key.encrypt_file(clearfile)
|
97
|
+
assert_equal cryptfile, clearfile + ".ez"
|
98
|
+
assert_file_not_exists clearfile
|
99
|
+
assert_file_exists cryptfile
|
100
|
+
assert_file_contains cryptfile, key.encrypt(CLEAR_TEXT)
|
101
|
+
|
102
|
+
# default behaviour: unlink cryptfile and remove suffix from filename
|
103
|
+
clearfile = key.decrypt_file cryptfile
|
104
|
+
assert_file_exists clearfile
|
105
|
+
assert_file_not_exists cryptfile
|
106
|
+
assert_file_contains clearfile, CLEAR_TEXT
|
107
|
+
FileUtils.rm [keyfile, clearfile, cryptfile], :force => true
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_filestuff_with_options
|
111
|
+
|
112
|
+
clearfile = 'lorem_ipsum.txt'
|
113
|
+
keyfile = 'lorem_ipsum.key'
|
114
|
+
algo, size = "aes-256-cbc", 32
|
115
|
+
|
116
|
+
File.open(clearfile, 'w') { |f| f.write(CLEAR_TEXT) }
|
117
|
+
assert_file_contains clearfile, CLEAR_TEXT
|
118
|
+
|
119
|
+
key = EzCrypto::Key.generate :algorithm => algo
|
120
|
+
|
121
|
+
# with options: keep the original file, auto-create a
|
122
|
+
# new filename with a user-defined suffix
|
123
|
+
cryptfile = key.encrypt_file(clearfile, nil, :autoclean => false, :suffix => '.Encrypted')
|
124
|
+
assert_equal cryptfile, clearfile + ".Encrypted", 'suffix was added'
|
125
|
+
assert_file_exists clearfile
|
126
|
+
assert_file_exists cryptfile
|
127
|
+
assert_file_permissions cryptfile, 0100600
|
128
|
+
|
129
|
+
assert_raises(Errno::EEXIST, "the original file would not be overwritten") {
|
130
|
+
key.decrypt_file(cryptfile, nil, :autoclean => false, :suffix => '.Encrypted')
|
131
|
+
}
|
132
|
+
FileUtils.rm [clearfile], :force => true
|
133
|
+
|
134
|
+
clearfile = key.decrypt_file(cryptfile, nil, :autoclean => false, :suffix => '.Encrypted')
|
135
|
+
assert_equal cryptfile, clearfile + ".Encrypted", 'suffix was removed'
|
136
|
+
assert_file_exists clearfile
|
137
|
+
assert_file_exists cryptfile
|
138
|
+
assert_file_permissions cryptfile, 0100600
|
139
|
+
assert_file_contains clearfile, CLEAR_TEXT
|
140
|
+
|
141
|
+
FileUtils.rm [keyfile, clearfile, cryptfile], :force => true
|
142
|
+
end
|
143
|
+
|
144
|
+
def assert_file_permissions(filename, mode, msg='')
|
145
|
+
fmode = File.stat(filename).mode
|
146
|
+
assert_equal fmode, mode, msg
|
147
|
+
end
|
148
|
+
|
149
|
+
def assert_file_exists(filename)
|
150
|
+
assert File.exists?(filename)
|
151
|
+
end
|
152
|
+
|
153
|
+
def assert_file_not_exists(filename)
|
154
|
+
assert !File.exists?(filename)
|
155
|
+
end
|
156
|
+
|
157
|
+
def assert_file_contains(filename, expected)
|
158
|
+
assert_file_exists(filename)
|
159
|
+
content = File.open(filename,'r').read
|
160
|
+
assert_equal expected, content
|
161
|
+
end
|
162
|
+
|
163
|
+
def assert_key_size(size,key)
|
164
|
+
assert_equal size,key.raw.size
|
165
|
+
end
|
166
|
+
|
167
|
+
def assert_generate_alg_key(algorithm,size)
|
168
|
+
key=EzCrypto::Key.generate :algorithm=>algorithm
|
169
|
+
assert_key_size size,key
|
170
|
+
end
|
171
|
+
|
172
|
+
def assert_with_password(password,salt,algorithm,size)
|
173
|
+
key=EzCrypto::Key.with_password password,salt,:algorithm=>algorithm
|
174
|
+
assert_key_size size,key
|
175
|
+
assert_equal key.raw,EzCrypto::Key.with_password( password,salt,:algorithm=>algorithm).raw
|
176
|
+
end
|
177
|
+
|
178
|
+
def assert_encoded_keys(size)
|
179
|
+
key=EzCrypto::Key.generate size
|
180
|
+
key2=EzCrypto::Key.decode(key.encode)
|
181
|
+
assert_equal key.raw, key2.raw
|
182
|
+
end
|
183
|
+
|
184
|
+
def assert_encrypt(clear)
|
185
|
+
ALGORITHMS.each do |alg|
|
186
|
+
key=EzCrypto::Key.generate :algorithm=>alg
|
187
|
+
encrypted=key.encrypt clear
|
188
|
+
assert_not_nil encrypted
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def assert_decrypt(clear)
|
193
|
+
ALGORITHMS.each do |alg|
|
194
|
+
key=EzCrypto::Key.generate :algorithm=>alg
|
195
|
+
encrypted=key.encrypt clear
|
196
|
+
assert_not_nil encrypted
|
197
|
+
assert_equal clear,key.decrypt(encrypted)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def assert_decrypt64(clear)
|
202
|
+
key=EzCrypto::Key.generate
|
203
|
+
encrypted=key.encrypt64 clear
|
204
|
+
assert_not_nil encrypted
|
205
|
+
assert_equal clear,key.decrypt64(encrypted)
|
206
|
+
end
|
207
|
+
|
208
|
+
ALGORITHMS=["aes128","bf","blowfish","des","des3","rc4","rc2"]
|
110
209
|
CLEAR_TEXT="Lorem ipsum dolor sit amet, suspendisse id interdum mus leo id. Sapien tempus consequat nullam, platea vitae sociis sed elementum et fermentum, vel praesent eget. Sed blandit augue, molestie mus sed habitant, semper voluptatibus neque, nullam a augue. Aptent imperdiet curabitur, quam quis laoreet. Dolor magna. Quis vestibulum amet eu arcu fringilla nibh, mi urna sunt dictumst nulla, elit quisque purus eros, sem hendrerit. Vulputate tortor rhoncus ac nonummy tortor nulla. Nunc id nunc luctus ligula."
|
111
210
|
end
|
112
211
|
|
212
|
+
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'action_pack'
|
6
|
+
require 'active_record'
|
7
|
+
#require 'active_support/binding_of_caller'
|
8
|
+
#require 'active_support/breakpoint'
|
9
|
+
|
10
|
+
|
11
|
+
unless defined?(RAILS_ROOT)
|
12
|
+
root_path = File.join(File.dirname(__FILE__), '..')
|
13
|
+
unless RUBY_PLATFORM =~ /mswin32/
|
14
|
+
require 'pathname'
|
15
|
+
root_path = Pathname.new(root_path).cleanpath.to_s
|
16
|
+
end
|
17
|
+
RAILS_ROOT = root_path
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
require 'active_record/fixtures'
|
22
|
+
require 'initializer'
|
23
|
+
|
24
|
+
Rails::Initializer.run(:set_load_path)
|
25
|
+
|
26
|
+
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
27
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
28
|
+
ActiveRecord::Base.establish_connection(
|
29
|
+
:adapter => "mysql",
|
30
|
+
:host => "localhost",
|
31
|
+
:username => "root",
|
32
|
+
:password => "",
|
33
|
+
:database => "crypto_test"
|
34
|
+
)
|
35
|
+
#load(File.dirname(__FILE__) + "/schema.rb")
|
36
|
+
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ezcrypto
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date:
|
6
|
+
version: "0.3"
|
7
|
+
date: 2006-02-25
|
8
8
|
summary: Simplified encryption library.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -32,17 +32,13 @@ files:
|
|
32
32
|
- README_ACTIVE_CRYPTO
|
33
33
|
- MIT-LICENSE
|
34
34
|
- CHANGELOG
|
35
|
+
- init.rb
|
35
36
|
- lib/active_crypto.rb
|
36
|
-
- lib/CVS
|
37
37
|
- lib/ezcrypto.rb
|
38
|
-
-
|
39
|
-
-
|
40
|
-
- lib/CVS/Root
|
41
|
-
- test/CVS
|
38
|
+
- test/active_crypto_test.rb
|
39
|
+
- test/database.yml
|
42
40
|
- test/ezcrypto_test.rb
|
43
|
-
- test/
|
44
|
-
- test/CVS/Repository
|
45
|
-
- test/CVS/Root
|
41
|
+
- test/test_helper.rb
|
46
42
|
test_files: []
|
47
43
|
rdoc_options: []
|
48
44
|
extra_rdoc_files: []
|
data/lib/CVS/Entries
DELETED
data/lib/CVS/Repository
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ezcrypto/lib
|
data/lib/CVS/Root
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
:ext:pelleb@rubyforge.net:/var/cvs/ezcrypto
|
data/test/CVS/Entries
DELETED
data/test/CVS/Repository
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ezcrypto/test
|
data/test/CVS/Root
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
:ext:pelleb@rubyforge.net:/var/cvs/ezcrypto
|