chintala-strongbox 0.6.1
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.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.textile +182 -0
- data/Rakefile +39 -0
- data/init.rb +1 -0
- data/lib/strongbox.rb +97 -0
- data/lib/strongbox/lock.rb +152 -0
- data/rails/init.rb +1 -0
- data/strongbox.gemspec +23 -0
- data/test/database.yml +4 -0
- data/test/fixtures/encrypted +0 -0
- data/test/fixtures/keypair.pem +24 -0
- data/test/method_key_test.rb +77 -0
- data/test/missing_attributes_test.rb +77 -0
- data/test/proc_key_test.rb +57 -0
- data/test/strongbox_multiply_test.rb +52 -0
- data/test/strongbox_test.rb +252 -0
- data/test/test_helper.rb +86 -0
- data/test/validations_test.rb +101 -0
- metadata +125 -0
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'../init.rb')
|
data/strongbox.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
3
|
+
require 'strongbox'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "chintala-strongbox"
|
7
|
+
s.version = Strongbox::VERSION
|
8
|
+
s.summary = "Secures ActiveRecord fields with public key encryption."
|
9
|
+
s.authors = ["Spike Ilacqua"]
|
10
|
+
s.email = "spike@stuff-things.net"
|
11
|
+
s.description = <<-EOF
|
12
|
+
Strongbox provides Public Key Encryption for ActiveRecord. By using a
|
13
|
+
public key sensitive information can be encrypted and stored automatically.
|
14
|
+
Once stored a password is required to access the information. dependencies
|
15
|
+
are specified in standard Ruby syntax.
|
16
|
+
EOF
|
17
|
+
s.homepage = "http://stuff-things.net/strongbox"
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
20
|
+
s.add_runtime_dependency 'activerecord'
|
21
|
+
s.add_development_dependency 'thoughtbot-shoulda'
|
22
|
+
s.add_development_dependency 'sqlite3'
|
23
|
+
end
|
data/test/database.yml
ADDED
Binary file
|
@@ -0,0 +1,24 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
Proc-Type: 4,ENCRYPTED
|
3
|
+
DEK-Info: DES-EDE3-CBC,317921A00FB0882F
|
4
|
+
|
5
|
+
f+GWBkcLJLsBUElOEKhqrtYgT1X4nixaZHD5x0VhmW2FrREz4vcqXrxwLTaRQJK/
|
6
|
+
vHFJ/7IVmEHScwEognSfw/wX2HMIHczoQT3ugsa29Nt7t1VLGy9jvN1+1f+g90xe
|
7
|
+
02jC7CYEKUJ3agZPox49i0/UN9OCIgdtKfecdDHYWyziob8yYTsUdDGyAXlPv0Kx
|
8
|
+
0MPSCRDtEh4UJ2PIFyw2HowkYeNss6uIte9rxJGINI11D9vmXR0pH0XyCwHQn+2T
|
9
|
+
ScHWg8BJ1rkBKydbKQ4vnfhGMjG+bZyrJXrJSoazXroseuhHu8QRUONm5Kl/zW1f
|
10
|
+
GP1CjIfTCQQZECYIa2tXTFdL9y2ZOCn8xit57SwEpmJMvZC58PkQX5+/aHPcOXhl
|
11
|
+
YrF+6FEfNpdBz9PUmv4Af2kTa88xZqm1Q3GtTOk7wsJpfeTMhU71KjA1pL9xNPrT
|
12
|
+
DnKhtfLGvcgo8Z9BGOiLFe9uQvhhprX7isc1XdysbMigsVIWLvZp9RxRp/zAn7fy
|
13
|
+
y56C6mc3tUwcq89RcxAn+bC75gwZO/hyVrnkhManOMfHTEiZXVybU9Ril3SZ+ry6
|
14
|
+
8AxMid0ZWbbtCHdDc5rHfXsGeFhJZxBbg/WtMxBPGHNByqs8sWUM9Z8YoK8WMYxV
|
15
|
+
GvC9RB4m0jgA4S3MEOMmKOXDuJxa7IgTgApVmLPl+sDOHGK3xAItYJJawJqOZQ1f
|
16
|
+
r+x/8g19CuehuflCxDo+D4/RJMqkOEq+0FGUqI8lHv6vR6+YpkGdrQQXUohBy67f
|
17
|
+
3Qym1ztZ8ygsttgJwnhwAfMh8FdIrVJc7NZ8pDiBZbg=
|
18
|
+
-----END RSA PRIVATE KEY-----
|
19
|
+
-----BEGIN PUBLIC KEY-----
|
20
|
+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9F1ipsLL+V68bGSJFqFLQKgXq
|
21
|
+
Glyyplx0s9KxgLbmbDICXpV7DceKaIBUkPZDx2DrlvjZmG+rG5ehdWNI7q/hupao
|
22
|
+
NF0WzEiOp+30gISeyl81Z/NAmhcwcOnZpbS9nl4JLaWrN7iGC1geNBNDo+lVbsm1
|
23
|
+
O2+Tlt8rjHsNjzgIzQIDAQAB
|
24
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class MethodKeyTest < Test::Unit::TestCase
|
4
|
+
context 'With an attribute containing a string for the key pair' do
|
5
|
+
setup do
|
6
|
+
@password = 'boost facile'
|
7
|
+
rebuild_model :key_pair => :key_pair_attribute
|
8
|
+
Dummy.class_eval do
|
9
|
+
attr_accessor :key_pair_attribute
|
10
|
+
end
|
11
|
+
|
12
|
+
@dummy = Dummy.new
|
13
|
+
@dummy.key_pair_attribute = File.read(File.join(FIXTURES_DIR,'keypair.pem'))
|
14
|
+
@dummy.secret = 'Shhhh'
|
15
|
+
end
|
16
|
+
|
17
|
+
should_encypted_and_decrypt
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'With a methods returning the key pair' do
|
21
|
+
setup do
|
22
|
+
@password = 'boost facile'
|
23
|
+
rebuild_model :key_pair => :key_pair_method
|
24
|
+
Dummy.class_eval do
|
25
|
+
def key_pair_method
|
26
|
+
File.read(File.join(FIXTURES_DIR,'keypair.pem'))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
@dummy = Dummy.new
|
31
|
+
@dummy.secret = 'Shhhh'
|
32
|
+
end
|
33
|
+
|
34
|
+
should_encypted_and_decrypt
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'With attributes containing strings for the keys' do
|
38
|
+
setup do
|
39
|
+
@password = 'boost facile'
|
40
|
+
rsa_key = OpenSSL::PKey::RSA.new(2048)
|
41
|
+
cipher = OpenSSL::Cipher::Cipher.new('des3')
|
42
|
+
rebuild_model :public_key => :public_key_attribute,
|
43
|
+
:private_key => :private_key_attribute
|
44
|
+
Dummy.class_eval do
|
45
|
+
attr_accessor :public_key_attribute, :private_key_attribute
|
46
|
+
end
|
47
|
+
@dummy = Dummy.new
|
48
|
+
@dummy.public_key_attribute = rsa_key.public_key.to_pem
|
49
|
+
@dummy.private_key_attribute = rsa_key.to_pem(cipher,@password)
|
50
|
+
@dummy.secret = 'Shhhh'
|
51
|
+
end
|
52
|
+
|
53
|
+
should_encypted_and_decrypt
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'With methods returning the keys' do
|
57
|
+
setup do
|
58
|
+
@password = 'boost facile'
|
59
|
+
rebuild_model :public_key => :public_key_method,
|
60
|
+
:private_key => :private_key_method
|
61
|
+
Dummy.class_eval do
|
62
|
+
def public_key_method
|
63
|
+
File.read(File.join(FIXTURES_DIR,'keypair.pem'))
|
64
|
+
end
|
65
|
+
|
66
|
+
def private_key_method
|
67
|
+
File.read(File.join(FIXTURES_DIR,'keypair.pem'))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
@dummy = Dummy.new
|
72
|
+
@dummy.secret = 'Shhhh'
|
73
|
+
end
|
74
|
+
|
75
|
+
should_encypted_and_decrypt
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class MissingAttribuesTest < Test::Unit::TestCase
|
4
|
+
context 'A Class with a secured field without a matching database column' do
|
5
|
+
setup do
|
6
|
+
ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
|
7
|
+
table.string :in_the_clear
|
8
|
+
end
|
9
|
+
rebuild_class {}
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'raise' do
|
13
|
+
assert_raise(Strongbox::StrongboxError) do
|
14
|
+
Dummy.class_eval do
|
15
|
+
encrypt_with_public_key :secret, :key_pair =>
|
16
|
+
File.join(FIXTURES_DIR,'keypair.pem')
|
17
|
+
end
|
18
|
+
@dummy = Dummy.new
|
19
|
+
@dummy.secret = 'Shhhh'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
teardown do
|
24
|
+
rebuild_model
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'A Class with a secured field missing symmetric database columns' do
|
29
|
+
setup do
|
30
|
+
ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
|
31
|
+
table.string :in_the_clear
|
32
|
+
table.string :secret
|
33
|
+
end
|
34
|
+
rebuild_class {}
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'raise' do
|
38
|
+
assert_raise(Strongbox::StrongboxError) do
|
39
|
+
Dummy.class_eval do
|
40
|
+
encrypt_with_public_key :secret, :key_pair =>
|
41
|
+
File.join(FIXTURES_DIR,'keypair.pem')
|
42
|
+
end
|
43
|
+
@dummy = Dummy.new
|
44
|
+
@dummy.secret = 'Shhhh'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
teardown do
|
49
|
+
rebuild_model
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'A Class with a secured field without a matching database column told not to check columns' do
|
54
|
+
setup do
|
55
|
+
ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
|
56
|
+
table.string :in_the_clear
|
57
|
+
end
|
58
|
+
rebuild_class {}
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'not raise' do
|
62
|
+
assert_nothing_raised do
|
63
|
+
Dummy.class_eval do
|
64
|
+
encrypt_with_public_key(:secret,
|
65
|
+
:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
|
66
|
+
:ensure_required_columns => false)
|
67
|
+
end
|
68
|
+
@dummy = Dummy.new
|
69
|
+
@dummy.secret = 'Shhhh'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
teardown do
|
74
|
+
rebuild_model
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class ProcKeyTest < Test::Unit::TestCase
|
4
|
+
context 'With a Proc returning a string for a key pair' do
|
5
|
+
setup do
|
6
|
+
@password = 'boost facile'
|
7
|
+
rebuild_model :key_pair => Proc.new {
|
8
|
+
File.read(File.join(FIXTURES_DIR,'keypair.pem'))
|
9
|
+
}
|
10
|
+
@dummy = Dummy.new
|
11
|
+
@dummy.secret = 'Shhhh'
|
12
|
+
end
|
13
|
+
|
14
|
+
should_encypted_and_decrypt
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'With a Proc returning a key object' do
|
18
|
+
setup do
|
19
|
+
@password = 'boost facile'
|
20
|
+
@private_key = OpenSSL::PKey::RSA.new(2048)
|
21
|
+
rebuild_model :key_pair => Proc.new { @private_key }
|
22
|
+
@dummy = Dummy.new
|
23
|
+
@dummy.secret = 'Shhhh'
|
24
|
+
end
|
25
|
+
|
26
|
+
should_encypted_and_decrypt
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'With Procs returning public and private key strings' do
|
30
|
+
setup do
|
31
|
+
@password = 'boost facile'
|
32
|
+
@key_pair = File.read(File.join(FIXTURES_DIR,'keypair.pem'))
|
33
|
+
|
34
|
+
rebuild_model :public_key => Proc.new { @key_pair },
|
35
|
+
:private_key => Proc.new { @key_pair }
|
36
|
+
@dummy = Dummy.new
|
37
|
+
@dummy.secret = 'Shhhh'
|
38
|
+
end
|
39
|
+
|
40
|
+
should_encypted_and_decrypt
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'With Procs returning public and private key objects' do
|
44
|
+
setup do
|
45
|
+
@password = 'boost facile'
|
46
|
+
@private_key = OpenSSL::PKey::RSA.new(2048)
|
47
|
+
@public_key = @private_key.public_key
|
48
|
+
|
49
|
+
rebuild_model :public_key => Proc.new { @public_key },
|
50
|
+
:private_key => Proc.new { @private_key }
|
51
|
+
@dummy = Dummy.new
|
52
|
+
@dummy.secret = 'Shhhh'
|
53
|
+
end
|
54
|
+
|
55
|
+
should_encypted_and_decrypt
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'test/test_helper'
|
3
|
+
|
4
|
+
class StrongboxMultiPlyTest < Test::Unit::TestCase
|
5
|
+
context 'A Class with two secured fields' do
|
6
|
+
setup do
|
7
|
+
@password = 'boost facile'
|
8
|
+
key_pair = File.join(FIXTURES_DIR,'keypair.pem')
|
9
|
+
Dummy.class_eval do
|
10
|
+
encrypt_with_public_key :secret, :segreto, :key_pair => key_pair
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'that is valid' do
|
15
|
+
setup do
|
16
|
+
@dummy = Dummy.new
|
17
|
+
@dummy.secret = 'I have a secret...'
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'return "*encrypted*" when the record is locked' do
|
21
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'return the secrets when unlocked' do
|
25
|
+
assert_equal 'I have a secret...', @dummy.secret.decrypt(@password)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'Using strings for keys' do
|
32
|
+
setup do
|
33
|
+
@password = 'boost facile'
|
34
|
+
key_pair = File.read(File.join(FIXTURES_DIR,'keypair.pem'))
|
35
|
+
public_key = OpenSSL::PKey::RSA.new(key_pair,"")
|
36
|
+
private_key = OpenSSL::PKey::RSA.new(key_pair,@password)
|
37
|
+
Dummy.class_eval do
|
38
|
+
encrypt_with_public_key :secret, :public_key => public_key, :private_key => private_key
|
39
|
+
end
|
40
|
+
@dummy = Dummy.new
|
41
|
+
@dummy.secret = 'Shhhh'
|
42
|
+
end
|
43
|
+
|
44
|
+
should 'return "*encrypted*" when locked' do
|
45
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'return secret when unlocked' do
|
49
|
+
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'test/test_helper'
|
3
|
+
|
4
|
+
class StrongboxTest < Test::Unit::TestCase
|
5
|
+
context 'A Class with a secured field' do
|
6
|
+
setup do
|
7
|
+
@password = 'boost facile'
|
8
|
+
rebuild_model :key_pair => File.join(FIXTURES_DIR,'keypair.pem')
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'not error when trying to also create a secure field' do
|
12
|
+
assert_nothing_raised do
|
13
|
+
Dummy.class_eval do
|
14
|
+
encrypt_with_public_key :secret
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'that is valid' do
|
20
|
+
setup do
|
21
|
+
@dummy = Dummy.new
|
22
|
+
@dummy.secret = 'Shhhh'
|
23
|
+
@dummy.in_the_clear = 'Hey you guys!'
|
24
|
+
end
|
25
|
+
|
26
|
+
should 'not change unencrypted fields' do
|
27
|
+
assert_equal 'Hey you guys!', @dummy.in_the_clear
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'return "*encrypted*" when locked' do
|
31
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'return secret when unlocked' do
|
35
|
+
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
|
36
|
+
end
|
37
|
+
|
38
|
+
should 'generate and store symmetric encryption key and IV' do
|
39
|
+
assert_not_nil @dummy.attributes['secret_key']
|
40
|
+
assert_not_nil @dummy.attributes['secret_iv']
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'raise on bad password' do
|
44
|
+
assert_raises(OpenSSL::PKey::RSAError) do
|
45
|
+
@dummy.secret.decrypt('letmein')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
should 'impliment to_json' do
|
50
|
+
assert_nothing_raised do
|
51
|
+
@dummy.secret.to_json
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'updating unencrypted fields' do
|
56
|
+
setup do
|
57
|
+
@dummy.in_the_clear = 'I see you...'
|
58
|
+
@dummy.save
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'not effect the secret' do
|
62
|
+
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'updating the secret' do
|
67
|
+
setup do
|
68
|
+
@dummy.secret = @new_secret = 'Don\'t tell'
|
69
|
+
@dummy.save
|
70
|
+
end
|
71
|
+
|
72
|
+
should 'update the secret' do
|
73
|
+
assert_equal @new_secret, @dummy.secret.decrypt(@password)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'with symmetric encryption disabled' do
|
78
|
+
setup do
|
79
|
+
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
|
80
|
+
:symmetric => :never)
|
81
|
+
@dummy = Dummy.new
|
82
|
+
@dummy.secret = 'Shhhh'
|
83
|
+
end
|
84
|
+
|
85
|
+
should 'return "*encrypted*" when locked' do
|
86
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
87
|
+
end
|
88
|
+
|
89
|
+
should 'return secret when unlocked' do
|
90
|
+
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
|
91
|
+
end
|
92
|
+
|
93
|
+
should 'allow decryption of other strings encrypted with the same key' do
|
94
|
+
encrypted_text = File.read(File.join(FIXTURES_DIR,'encrypted'))
|
95
|
+
assert_equal 'Setec Astronomy', @dummy.secret.decrypt(@password, encrypted_text)
|
96
|
+
end
|
97
|
+
|
98
|
+
should 'not generate and store symmetric encryption key and IV' do
|
99
|
+
assert_nil @dummy.attributes['secret_key']
|
100
|
+
assert_nil @dummy.attributes['secret_iv']
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'with Base64 encoding enabled' do
|
106
|
+
setup do
|
107
|
+
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
|
108
|
+
:base64 => true)
|
109
|
+
@dummy = Dummy.new
|
110
|
+
@dummy.secret = 'Shhhh'
|
111
|
+
end
|
112
|
+
|
113
|
+
should 'Base64 encode the ciphertext' do
|
114
|
+
# Base64 encoded text is limited to the charaters A–Z, a–z, and 0–9,
|
115
|
+
# and is padded with 0 to 2 equal-signs
|
116
|
+
assert_match /^[0-9A-Za-z+\/]+={0,2}$/, @dummy.attributes['secret']
|
117
|
+
assert_match /^[0-9A-Za-z+\/]+={0,2}$/, @dummy.attributes['secret_key']
|
118
|
+
assert_match /^[0-9A-Za-z+\/]+={0,2}$/, @dummy.attributes['secret_iv']
|
119
|
+
end
|
120
|
+
|
121
|
+
should 'encrypt the data' do
|
122
|
+
assert_not_equal @dummy.attributes['secret'], 'Shhhh'
|
123
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
124
|
+
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'using blowfish cipher instead of AES' do
|
130
|
+
setup do
|
131
|
+
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
|
132
|
+
:symmetric_cipher => 'bf-cbc')
|
133
|
+
@dummy = Dummy.new
|
134
|
+
@dummy.secret = 'Shhhh'
|
135
|
+
end
|
136
|
+
|
137
|
+
should 'encrypt the data' do
|
138
|
+
assert_not_equal @dummy.attributes['secret'], 'Shhhh'
|
139
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
140
|
+
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'when a public key is not provided' do
|
146
|
+
setup do
|
147
|
+
rebuild_class
|
148
|
+
@dummy = Dummy.new
|
149
|
+
end
|
150
|
+
|
151
|
+
should 'raise on encrypt' do
|
152
|
+
assert_raises(Strongbox::StrongboxError) do
|
153
|
+
@dummy.secret = 'Shhhh'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'when a private key is not provided' do
|
159
|
+
setup do
|
160
|
+
@password = 'boost facile'
|
161
|
+
rebuild_class(:public_key => File.join(FIXTURES_DIR,'keypair.pem'))
|
162
|
+
@dummy = Dummy.new(:secret => 'Shhhh')
|
163
|
+
end
|
164
|
+
|
165
|
+
should 'raise on decrypt with a password' do
|
166
|
+
assert_raises(Strongbox::StrongboxError) do
|
167
|
+
@dummy.secret.decrypt(@password)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
should 'return "*encrypted*" when still locked' do
|
172
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "when an unencrypted public key is used" do
|
177
|
+
setup do
|
178
|
+
rebuild_class(:public_key => generate_key_pair.public_key)
|
179
|
+
@dummy = Dummy.new(:secret => 'Shhhh')
|
180
|
+
end
|
181
|
+
|
182
|
+
should "encrypt the data" do
|
183
|
+
assert_not_equal @dummy.attributes['secret'], 'Shhhh'
|
184
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "when an unencrypted key pair is used" do
|
189
|
+
setup do
|
190
|
+
rebuild_class(:key_pair => generate_key_pair)
|
191
|
+
@dummy = Dummy.new(:secret => 'Shhhh')
|
192
|
+
end
|
193
|
+
|
194
|
+
should "encrypt the data" do
|
195
|
+
assert_not_equal @dummy.attributes['secret'], 'Shhhh'
|
196
|
+
assert_equal "Shhhh", @dummy.secret.decrypt('')
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'A Class with two secured fields' do
|
201
|
+
setup do
|
202
|
+
@password = 'boost facile'
|
203
|
+
key_pair = File.join(FIXTURES_DIR,'keypair.pem')
|
204
|
+
Dummy.class_eval do
|
205
|
+
encrypt_with_public_key :secret, :key_pair => key_pair
|
206
|
+
encrypt_with_public_key :segreto, :key_pair => key_pair,
|
207
|
+
:symmetric => :never
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context 'that is valid' do
|
212
|
+
setup do
|
213
|
+
@dummy = Dummy.new
|
214
|
+
@dummy.secret = 'I have a secret...'
|
215
|
+
@dummy.segreto = 'Ho un segreto...'
|
216
|
+
end
|
217
|
+
|
218
|
+
should 'return "*encrypted*" when the record is locked' do
|
219
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
220
|
+
assert_equal '*encrypted*', @dummy.segreto.decrypt
|
221
|
+
end
|
222
|
+
|
223
|
+
should 'return the secrets when unlocked' do
|
224
|
+
assert_equal 'I have a secret...', @dummy.secret.decrypt(@password)
|
225
|
+
assert_equal 'Ho un segreto...', @dummy.segreto.decrypt(@password)
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'Using strings for keys' do
|
232
|
+
setup do
|
233
|
+
@password = 'boost facile'
|
234
|
+
key_pair = File.read(File.join(FIXTURES_DIR,'keypair.pem'))
|
235
|
+
public_key = OpenSSL::PKey::RSA.new(key_pair,"")
|
236
|
+
private_key = OpenSSL::PKey::RSA.new(key_pair,@password)
|
237
|
+
Dummy.class_eval do
|
238
|
+
encrypt_with_public_key :secret, :public_key => public_key, :private_key => private_key
|
239
|
+
end
|
240
|
+
@dummy = Dummy.new
|
241
|
+
@dummy.secret = 'Shhhh'
|
242
|
+
end
|
243
|
+
|
244
|
+
should 'return "*encrypted*" when locked' do
|
245
|
+
assert_equal '*encrypted*', @dummy.secret.decrypt
|
246
|
+
end
|
247
|
+
|
248
|
+
should 'return secret when unlocked' do
|
249
|
+
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|