vault-tree 0.3.4 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/CHANGE_LOG.md +27 -0
- data/README.md +15 -73
- data/features/contracts/asymmetric_vault.feature +69 -2
- data/features/contracts/block_chain_key_transfer.feature +59 -0
- data/features/contracts/one_two_three.feature +109 -1
- data/features/contracts/readme.md +5 -6
- data/features/contracts_and_vaults.md +19 -24
- data/features/decision_tree.md +1 -1
- data/features/exceptions.feature +54 -43
- data/features/install_and_usage.md +38 -33
- data/features/keywords/assembled_shamir_key.feature +17 -17
- data/features/keywords/dh_key.feature +5 -5
- data/features/keywords/external_input.feature +35 -0
- data/features/keywords/external_key.feature +24 -0
- data/features/keywords/key.feature +3 -3
- data/features/keywords/random_number.feature +3 -3
- data/features/keywords/shamir_key_shares.feature +29 -0
- data/features/keywords/shamir_share.feature +40 -0
- data/features/keywords/split_key.feature +10 -9
- data/features/keywords/unlocked.feature +3 -3
- data/features/readme.md +1 -1
- data/features/steps/asymmetric_vault.steps.rb +14 -21
- data/features/steps/block_chain_key_transfer.steps.rb +17 -22
- data/features/steps/core.steps.rb +60 -71
- data/features/steps/exceptions.steps.rb +27 -64
- data/features/steps/external_input.steps.rb +17 -0
- data/features/steps/one_two_three.steps.rb +21 -27
- data/features/steps/secret_sharing.steps.rb +36 -19
- data/lib/vault-tree.rb +1 -1
- data/lib/vault-tree/contract/content_ciphertext.rb +33 -0
- data/lib/vault-tree/contract/content_plaintext.rb +33 -0
- data/lib/vault-tree/contract/contract.rb +15 -72
- data/lib/vault-tree/contract/contract_header.rb +11 -0
- data/lib/vault-tree/contract/vault.rb +24 -74
- data/lib/vault-tree/contract/vault_key.rb +21 -0
- data/lib/vault-tree/contract/vault_list.rb +56 -0
- data/lib/vault-tree/exceptions/empty_vault.rb +18 -3
- data/lib/vault-tree/exceptions/failed_lock_attempt.rb +18 -0
- data/lib/vault-tree/exceptions/failed_unlock_attempt.rb +23 -1
- data/lib/vault-tree/exceptions/invalid_external_input.rb +16 -0
- data/lib/vault-tree/exceptions/{missing_passphrase.rb → invalid_shamir_split.rb} +2 -1
- data/lib/vault-tree/exceptions/library_exception.rb +64 -0
- data/lib/vault-tree/exceptions/missing_partner_decryption_key.rb +11 -1
- data/lib/vault-tree/exceptions/unsupported_keyword.rb +17 -1
- data/lib/vault-tree/exceptions/vault_does_not_exist.rb +8 -1
- data/lib/vault-tree/keywords/assembled_shamir_key.rb +1 -1
- data/lib/vault-tree/keywords/contents.rb +1 -1
- data/lib/vault-tree/keywords/dh_key.rb +2 -2
- data/lib/vault-tree/keywords/external_input.rb +58 -0
- data/lib/vault-tree/keywords/external_key.rb +20 -0
- data/lib/vault-tree/keywords/key.rb +7 -1
- data/lib/vault-tree/keywords/keyword_interpreter.rb +5 -3
- data/lib/vault-tree/keywords/public_encryption_key.rb +1 -5
- data/lib/vault-tree/keywords/shamir_key_shares.rb +18 -0
- data/lib/vault-tree/keywords/shamir_share.rb +18 -0
- data/lib/vault-tree/keywords/split_key.rb +1 -1
- data/lib/vault-tree/lock_smith.rb +7 -8
- data/lib/vault-tree/lock_smith/{generated_shamir_key.rb → shamir_key_shares.rb} +22 -21
- data/lib/vault-tree/lock_smith/{split_key.rb → split_key_crypto.rb} +0 -0
- data/lib/vault-tree/version.rb +1 -1
- data/spec/assembled_shamir_key_spec.rb +0 -1
- data/spec/custom_exception_spec.rb +81 -0
- data/spec/lock_smith_spec.rb +0 -48
- data/spec/secret_sharing_spec.rb +0 -1
- data/spec/shamir_key_shares_spec.rb +27 -0
- data/vault-tree.gemspec +1 -1
- metadata +33 -139
- data/Gemfile.lock +0 -53
- data/VagrantFile +0 -30
- data/features/keywords/external_data.feature +0 -11
- data/features/keywords/generated_shamir_key.feature +0 -55
- data/features/keywords/master_passphrase.feature +0 -68
- data/features/manipulating_contracts.md +0 -84
- data/features/support/contract_fixtures/asymmetric_vault.0.1.0.json +0 -69
- data/features/support/contract_fixtures/blank_simple_test_contract.json +0 -14
- data/features/support/contract_fixtures/block_chain_key_transfer.0.1.0.json +0 -59
- data/features/support/contract_fixtures/broken_contract.json +0 -55
- data/features/support/contract_fixtures/one_two_three.0.7.0.json +0 -108
- data/features/support/contract_fixtures/simple_test_contract.json +0 -14
- data/features/support/contract_fixtures/template.json +0 -33
- data/lib/vault-tree/contract/close_validator.rb +0 -28
- data/lib/vault-tree/contract/doorman.rb +0 -113
- data/lib/vault-tree/contract/open_validator.rb +0 -20
- data/lib/vault-tree/exceptions/exception_template.erb +0 -0
- data/lib/vault-tree/exceptions/fill_attempt_master_password.rb +0 -6
- data/lib/vault-tree/exceptions/missing_external_data.rb +0 -6
- data/lib/vault-tree/exceptions/vault_tree_exception.rb +0 -25
- data/lib/vault-tree/keywords/external_data.rb +0 -32
- data/lib/vault-tree/keywords/generated_shamir_key.rb +0 -57
- data/lib/vault-tree/keywords/master_passphrase.rb +0 -9
- data/spec/generated_shamir_key_spec.rb +0 -52
- data/support/cookbooks/ark/.gitignore +0 -12
- data/support/cookbooks/ark/.kitchen.yml +0 -34
- data/support/cookbooks/ark/.travis.yml +0 -6
- data/support/cookbooks/ark/Berksfile +0 -9
- data/support/cookbooks/ark/CHANGELOG.md +0 -87
- data/support/cookbooks/ark/CONTRIBUTING.md +0 -257
- data/support/cookbooks/ark/README.md +0 -301
- data/support/cookbooks/ark/Rakefile +0 -36
- data/support/cookbooks/ark/TESTING.md +0 -25
- data/support/cookbooks/ark/Toftfile +0 -15
- data/support/cookbooks/ark/attributes/default.rb +0 -6
- data/support/cookbooks/ark/chefignore +0 -96
- data/support/cookbooks/ark/files/default/foo.tar.gz +0 -0
- data/support/cookbooks/ark/files/default/foo.tbz +0 -0
- data/support/cookbooks/ark/files/default/foo.tgz +0 -0
- data/support/cookbooks/ark/files/default/foo.zip +0 -0
- data/support/cookbooks/ark/files/default/tests/minitest/default_test.rb +0 -0
- data/support/cookbooks/ark/files/default/tests/minitest/support/helpers.rb +0 -0
- data/support/cookbooks/ark/files/default/tests/minitest/test_test.rb +0 -94
- data/support/cookbooks/ark/libraries/default.rb +0 -167
- data/support/cookbooks/ark/metadata.rb +0 -13
- data/support/cookbooks/ark/providers/default.rb +0 -370
- data/support/cookbooks/ark/recipes/default.rb +0 -31
- data/support/cookbooks/ark/recipes/test.rb +0 -138
- data/support/cookbooks/ark/resources/default.rb +0 -54
- data/support/cookbooks/ark/templates/default/add_to_path.sh.erb +0 -1
- data/support/cookbooks/ark/test/support/Gemfile +0 -4
- data/support/cookbooks/build-essential/README.md +0 -24
- data/support/cookbooks/build-essential/metadata.rb +0 -10
- data/support/cookbooks/build-essential/recipes/default.rb +0 -45
- data/support/cookbooks/chruby/.gitignore +0 -15
- data/support/cookbooks/chruby/.kitchen.yml +0 -26
- data/support/cookbooks/chruby/.ruby_version +0 -1
- data/support/cookbooks/chruby/Berksfile +0 -3
- data/support/cookbooks/chruby/Gemfile +0 -7
- data/support/cookbooks/chruby/LICENSE +0 -14
- data/support/cookbooks/chruby/README.md +0 -92
- data/support/cookbooks/chruby/Rakefile +0 -7
- data/support/cookbooks/chruby/Thorfile +0 -6
- data/support/cookbooks/chruby/Vagrantfile +0 -86
- data/support/cookbooks/chruby/attributes/default.rb +0 -10
- data/support/cookbooks/chruby/chefignore +0 -96
- data/support/cookbooks/chruby/metadata.rb +0 -11
- data/support/cookbooks/chruby/recipes/default.rb +0 -43
- data/support/cookbooks/chruby/recipes/system.rb +0 -25
- data/support/cookbooks/chruby/templates/default/chruby.sh.erb +0 -22
- data/support/cookbooks/chruby/test/integration/default/bash/embedded_test.sh +0 -1
- data/support/cookbooks/git/.gitignore +0 -14
- data/support/cookbooks/git/.kitchen.yml +0 -46
- data/support/cookbooks/git/Berksfile +0 -8
- data/support/cookbooks/git/CHANGELOG.md +0 -87
- data/support/cookbooks/git/CONTRIBUTING +0 -29
- data/support/cookbooks/git/Gemfile +0 -3
- data/support/cookbooks/git/LICENSE +0 -201
- data/support/cookbooks/git/README.md +0 -115
- data/support/cookbooks/git/TESTING.md +0 -25
- data/support/cookbooks/git/attributes/default.rb +0 -40
- data/support/cookbooks/git/metadata.rb +0 -35
- data/support/cookbooks/git/recipes/default.rb +0 -53
- data/support/cookbooks/git/recipes/server.rb +0 -58
- data/support/cookbooks/git/recipes/source.rb +0 -49
- data/support/cookbooks/git/recipes/windows.rb +0 -37
- data/support/cookbooks/git/templates/default/git-xinetd.d.erb +0 -10
- data/support/cookbooks/git/templates/default/sv-git-daemon-log-run.erb +0 -2
- data/support/cookbooks/git/templates/default/sv-git-daemon-run.erb +0 -3
- data/support/cookbooks/install_ruby/README.md +0 -3
- data/support/cookbooks/install_ruby/metadata.rb +0 -10
- data/support/cookbooks/install_ruby/recipes/default.rb +0 -14
- data/support/cookbooks/ruby_build/.gitignore +0 -6
- data/support/cookbooks/ruby_build/.kitchen.yml +0 -31
- data/support/cookbooks/ruby_build/.travis.yml +0 -4
- data/support/cookbooks/ruby_build/Berksfile +0 -10
- data/support/cookbooks/ruby_build/CHANGELOG.md +0 -72
- data/support/cookbooks/ruby_build/Gemfile +0 -14
- data/support/cookbooks/ruby_build/README.md +0 -338
- data/support/cookbooks/ruby_build/Rakefile +0 -21
- data/support/cookbooks/ruby_build/attributes/default.rb +0 -67
- data/support/cookbooks/ruby_build/chefignore +0 -53
- data/support/cookbooks/ruby_build/libraries/ruby_build_recipe_helpers.rb +0 -40
- data/support/cookbooks/ruby_build/metadata.rb +0 -18
- data/support/cookbooks/ruby_build/providers/ruby.rb +0 -88
- data/support/cookbooks/ruby_build/recipes/default.rb +0 -69
- data/support/cookbooks/ruby_build/resources/ruby.rb +0 -33
- data/support/cookbooks/ruby_build/test/cookbooks/alltherubies/metadata.rb +0 -10
- data/support/cookbooks/ruby_build/test/cookbooks/alltherubies/recipes/default.rb +0 -59
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/_verify_tests.bash +0 -33
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_1.8.7.bats +0 -29
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_1.9.2.bats +0 -18
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_1.9.3.bats +0 -18
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_2.0.0.bats +0 -18
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_jruby.bats +0 -20
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_rbx.bats +0 -18
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_ree.bats +0 -19
- data/support/cookbooks/ruby_build/test/integration/installation/bats/installation.bats +0 -6
- data/support/scripts/libsodium_ubuntu.sh +0 -80
- data/support/tasks/.gitkeep +0 -0
- data/support/tasks/libsodium_install.rb +0 -57
|
@@ -1,68 +1,18 @@
|
|
|
1
|
-
Given(/^a valid blank contract$/) do
|
|
2
|
-
contract_path = VaultTree::PathHelpers.reference_contract
|
|
3
|
-
@contract_json = File.read(contract_path)
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
When(/^I attempt fill a vault without providing a master passphrase$/) do
|
|
7
|
-
begin
|
|
8
|
-
@contract = VaultTree::Contract.new(@contract_json)
|
|
9
|
-
@contract = @contract.close_vault('message')
|
|
10
|
-
rescue => e
|
|
11
|
-
@exception = e
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
1
|
Then(/^a MissingPassphrase exception is raised$/) do
|
|
16
2
|
@exception.should be_an_instance_of(VaultTree::Exceptions::MissingPassphrase)
|
|
17
3
|
end
|
|
18
4
|
|
|
19
5
|
Given(/^this broken contract:$/) do |string|
|
|
20
|
-
@
|
|
21
|
-
@contract = VaultTree::Contract.new(@contract_json, master_passphrase: 'TEST_USER', external_data: {})
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
Given(/^the broken contract$/) do
|
|
25
|
-
contract_path = VaultTree::PathHelpers.broken_contract
|
|
26
|
-
@contract_json = File.read(contract_path)
|
|
27
|
-
@contract = VaultTree::Contract.new(@contract_json, master_passphrase: 'TEST_USER', external_data: {})
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
When(/^I attempt lock a vault with External Data that does not exists$/) do
|
|
31
|
-
@contract = VaultTree::Contract.new(@contract_json, master_passphrase: 'TEST_USER', external_data: nil )
|
|
32
|
-
begin
|
|
33
|
-
@contract = @contract.close_vault('missing_external_data_vault')
|
|
34
|
-
rescue => e
|
|
35
|
-
@exception = e
|
|
36
|
-
end
|
|
6
|
+
@contract = string
|
|
37
7
|
end
|
|
38
8
|
|
|
39
9
|
When(/^I lock the data away$/) do
|
|
40
|
-
@contract = VaultTree::Contract.new(@
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
When(/^I attempt to unlock a vault with External Data that does not exists$/) do
|
|
44
|
-
begin
|
|
45
|
-
@contract = @contract.retrieve_contents('missing_external_data_vault')
|
|
46
|
-
rescue => e
|
|
47
|
-
@exception = e
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
When(/^I attempt fill a vault with External Data that does not exists$/) do
|
|
52
|
-
begin
|
|
53
|
-
@contract = @contract.close_vault('missing_external_data_vault')
|
|
54
|
-
rescue => e
|
|
55
|
-
@exception = e
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
Then(/^a MissingExternalData exception is raised$/) do
|
|
60
|
-
@exception.should be_an_instance_of(VaultTree::Exceptions::MissingExternalData)
|
|
10
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('missing_external_data_vault')
|
|
61
11
|
end
|
|
62
12
|
|
|
63
13
|
When(/^I attempt fill a vault with my Master Password$/) do
|
|
64
14
|
begin
|
|
65
|
-
@contract = @contract.close_vault('fill_with_master_pass_vault')
|
|
15
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('fill_with_master_pass_vault')
|
|
66
16
|
rescue => e
|
|
67
17
|
@exception = e
|
|
68
18
|
end
|
|
@@ -74,7 +24,7 @@ end
|
|
|
74
24
|
|
|
75
25
|
When(/^I attempt to open an empty vault$/) do
|
|
76
26
|
begin
|
|
77
|
-
@contents = @contract.
|
|
27
|
+
@contents = VaultTree::Contract.new(@contract).open_vault('empty_vault')
|
|
78
28
|
rescue => e
|
|
79
29
|
@exception = e
|
|
80
30
|
end
|
|
@@ -86,7 +36,7 @@ end
|
|
|
86
36
|
|
|
87
37
|
When(/^I attempt to open a vault that does not exists$/) do
|
|
88
38
|
begin
|
|
89
|
-
@contents = @contract.
|
|
39
|
+
@contents = VaultTree::Contract.new(@contract).open_vault('non_existant_vault')
|
|
90
40
|
rescue => e
|
|
91
41
|
@exception = e
|
|
92
42
|
end
|
|
@@ -94,7 +44,7 @@ end
|
|
|
94
44
|
|
|
95
45
|
When(/^I attempt to close a vault that does not exists$/) do
|
|
96
46
|
begin
|
|
97
|
-
@contents = @contract.close_vault('non_existant_vault')
|
|
47
|
+
@contents = VaultTree::Contract.new(@contract).close_vault('non_existant_vault')
|
|
98
48
|
rescue => e
|
|
99
49
|
@exception = e
|
|
100
50
|
end
|
|
@@ -106,7 +56,7 @@ end
|
|
|
106
56
|
|
|
107
57
|
When(/^I attempt fill a vault with an unsupported Keyword$/) do
|
|
108
58
|
begin
|
|
109
|
-
@contract = @contract.close_vault('unsupported_keyword')
|
|
59
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('unsupported_keyword')
|
|
110
60
|
rescue => e
|
|
111
61
|
@exception = e
|
|
112
62
|
end
|
|
@@ -118,7 +68,7 @@ end
|
|
|
118
68
|
|
|
119
69
|
When(/^I attempt to fill with an encryption key without first establishing the decryption key$/) do
|
|
120
70
|
begin
|
|
121
|
-
@contract = @contract.close_vault('orphaned_public_key')
|
|
71
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('orphaned_public_key')
|
|
122
72
|
rescue => e
|
|
123
73
|
@exception = e
|
|
124
74
|
end
|
|
@@ -128,15 +78,15 @@ Then(/^a MissingPartnerDecryptionKey exception is raised$/) do
|
|
|
128
78
|
@exception.should be_an_instance_of(VaultTree::Exceptions::MissingPartnerDecryptionKey)
|
|
129
79
|
end
|
|
130
80
|
|
|
131
|
-
When(/^I lock a vault with External
|
|
81
|
+
When(/^I lock a vault with External Input and attempt to unlock with the wrong External Input$/) do
|
|
132
82
|
locking_key = VaultTree::LockSmith.new().generate_secret_key
|
|
133
|
-
@contract = VaultTree::Contract.new(@
|
|
134
|
-
@contract = @contract.close_vault('
|
|
135
|
-
@
|
|
83
|
+
@contract = VaultTree::Contract.new(@contract).as_json
|
|
84
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('some_random_vault', right_secret: '5dd0abe3335d6f0ceab00e44a9d41a030c2a59802ffd6b42464c01f1c7fbdd68')
|
|
85
|
+
@contract = VaultTree::Contract.new(@contract).as_json
|
|
136
86
|
begin
|
|
137
87
|
wrong_unlocking_key = VaultTree::LockSmith.new().generate_secret_key
|
|
138
|
-
@contract = VaultTree::Contract.new(@
|
|
139
|
-
|
|
88
|
+
@contract = VaultTree::Contract.new(@contract).as_json
|
|
89
|
+
@contents = VaultTree::Contract.new(@contract).open_vault('some_random_vault', wrong_secret: '7dd0abe3335d6f0ceab00e44a9d41a030c2a59802ffd6b42464c01f1c7fbdd68')
|
|
140
90
|
rescue => e
|
|
141
91
|
@exception = e
|
|
142
92
|
end
|
|
@@ -145,3 +95,16 @@ end
|
|
|
145
95
|
Then(/^a FailedUnlockAttempt exception is raised$/) do
|
|
146
96
|
@exception.should be_an_instance_of(VaultTree::Exceptions::FailedUnlockAttempt)
|
|
147
97
|
end
|
|
98
|
+
|
|
99
|
+
When(/^I attempt lock a vault with External Input that does not exists$/) do
|
|
100
|
+
@contract = VaultTree::Contract.new(@contract).as_json
|
|
101
|
+
begin
|
|
102
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('missing_external_input_vault', empty_value: '')
|
|
103
|
+
rescue => e
|
|
104
|
+
@exception = e
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
Then(/^an InvalidExternalInput exception is raised$/) do
|
|
109
|
+
@exception.should be_an_instance_of(VaultTree::Exceptions::InvalidExternalInput)
|
|
110
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
When(/^I lock the external input in a vault using a symmetric vault key$/) do
|
|
2
|
+
@secret = "#{VaultTree::LockSmith.new(message: 'secret_string').secure_hash}"
|
|
3
|
+
@contract = VaultTree::Contract.new(@contract).as_json
|
|
4
|
+
@external_input = {msg: 'You Opened the Vault!', secret: @secret}
|
|
5
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('message', @external_input)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
Then(/^I can recover the input message using the same key$/) do
|
|
9
|
+
VaultTree::Contract.new(@contract).open_vault('message', secret: @secret).should == @external_input[:msg]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
When(/^I lock the external input in a vault using an external key$/) do
|
|
13
|
+
@secret = "MY SECRET KEY THAT IS NOT THE PROPER NUMBER OF BYTES"
|
|
14
|
+
@contract = VaultTree::Contract.new(@contract).as_json
|
|
15
|
+
@external_input = {msg: 'You Opened the Vault!', secret: @secret}
|
|
16
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('message', @external_input)
|
|
17
|
+
end
|
|
@@ -1,57 +1,51 @@
|
|
|
1
1
|
Given(/^Alice has the blank contract$/) do
|
|
2
|
-
contract_path = VaultTree::PathHelpers.core_contracts('one_two_three.0.7.0.json')
|
|
3
|
-
@contract_json = File.read(contract_path)
|
|
4
2
|
end
|
|
5
3
|
|
|
6
4
|
# Change this to just attributes vice public attributes
|
|
7
5
|
When(/^she locks all of her attributes$/) do
|
|
8
|
-
@
|
|
9
|
-
@contract = @contract.close_vault('alice_decryption_key')
|
|
10
|
-
@contract = @contract.close_vault('alice_public_encryption_key')
|
|
6
|
+
@alice_contract_secret_key = "#{VaultTree::LockSmith.new(message: 'ALICE_SECURE_PASS').secure_hash}"
|
|
7
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('alice_decryption_key', acs_key: @alice_contract_secret_key)
|
|
8
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('alice_public_encryption_key', acs_key: @alice_contract_secret_key)
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
When(/^she sends the contract to Bob$/) do
|
|
14
|
-
@
|
|
15
|
-
@
|
|
16
|
-
@contract = VaultTree::Contract.new(@contract_json, master_passphrase: 'BOB_SECURE_PASS', external_data: @bobs_external_data)
|
|
12
|
+
@bob_contract_secret_key = "#{VaultTree::LockSmith.new(message: 'BOB_SECURE_PASS').secure_hash}"
|
|
13
|
+
@congratulations_message = "CONGRATS! YOU OPENED THE THIRD VAULT."
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
Then(/^Bob can access all of her public attributes$/) do
|
|
20
|
-
@contents = @contract.
|
|
17
|
+
@contents = VaultTree::Contract.new(@contract).open_vault('alice_public_encryption_key')
|
|
21
18
|
end
|
|
22
19
|
|
|
23
20
|
When(/^Bob locks his attributes$/) do
|
|
24
|
-
|
|
25
|
-
@contract = @contract.close_vault('bob_decryption_key')
|
|
21
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('bob_decryption_key', bcs_key: @bob_contract_secret_key)
|
|
26
22
|
# Verify can reopen
|
|
27
|
-
@contract.
|
|
23
|
+
VaultTree::Contract.new(@contract).open_vault('bob_decryption_key', bcs_key: @bob_contract_secret_key)
|
|
28
24
|
|
|
29
|
-
@contract = @contract.close_vault('congratulations_message')
|
|
25
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('congratulations_message', bcs_key: @bob_contract_secret_key, msg: @congratulations_message)
|
|
30
26
|
# Verify can reopen
|
|
31
|
-
@contract.
|
|
27
|
+
VaultTree::Contract.new(@contract).open_vault('congratulations_message', bcs_key: @bob_contract_secret_key)
|
|
32
28
|
|
|
33
|
-
@contract = @contract.close_vault('vault_two_key')
|
|
29
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('vault_two_key', bcs_key: @bob_contract_secret_key)
|
|
34
30
|
# Verify they can reopen
|
|
35
|
-
@contract.
|
|
31
|
+
VaultTree::Contract.new(@contract).open_vault('vault_two_key', bcs_key: @bob_contract_secret_key)
|
|
36
32
|
|
|
37
|
-
@contract = @contract.close_vault('vault_three_key')
|
|
33
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('vault_three_key', bcs_key: @bob_contract_secret_key)
|
|
38
34
|
# Verify they can reopen
|
|
39
|
-
@contract.
|
|
35
|
+
VaultTree::Contract.new(@contract).open_vault('vault_three_key', bcs_key: @bob_contract_secret_key)
|
|
40
36
|
|
|
41
|
-
@contract = @contract.close_vault('bob_public_encryption_key')
|
|
37
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('bob_public_encryption_key', bcs_key: @bob_contract_secret_key)
|
|
42
38
|
# Verify they can reopen
|
|
43
|
-
@contract.
|
|
39
|
+
VaultTree::Contract.new(@contract).open_vault('bob_public_encryption_key', bcs_key: @bob_contract_secret_key)
|
|
44
40
|
end
|
|
45
41
|
|
|
46
42
|
When(/^He fills and locks each of the three main vaults$/) do
|
|
47
|
-
@contract = @contract.close_vault('first')
|
|
48
|
-
@contract = @contract.close_vault('second')
|
|
49
|
-
@contract = @contract.close_vault('third')
|
|
43
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('first', bcs_key: @bob_contract_secret_key)
|
|
44
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('second', bcs_key: @bob_contract_secret_key)
|
|
45
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('third', bcs_key: @bob_contract_secret_key)
|
|
50
46
|
end
|
|
51
47
|
|
|
52
48
|
Then(/^Alice can execute the contract to recover the final message$/) do
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
puts @contract.retrieve_contents('third')
|
|
56
|
-
@contract.retrieve_contents('third').should == @bobs_external_data['congratulations_message']
|
|
49
|
+
puts VaultTree::Contract.new(@contract).open_vault('third', acs_key: @alice_contract_secret_key)
|
|
50
|
+
VaultTree::Contract.new(@contract).open_vault('third', acs_key: @alice_contract_secret_key).should == @congratulations_message
|
|
57
51
|
end
|
|
@@ -4,33 +4,50 @@ Given(/^I have a blank secret sharing contract$/) do
|
|
|
4
4
|
@contract = VaultTree::Contract.new(@contract_json)
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
@
|
|
7
|
+
Then(/^key shares are created and locked away in their cooresponding vaults$/) do
|
|
8
|
+
VaultTree::Contract.new(@contract).vault_closed?('s_1').should be true
|
|
9
|
+
VaultTree::Contract.new(@contract).vault_closed?('s_2').should be true
|
|
10
|
+
VaultTree::Contract.new(@contract).vault_closed?('s_3').should be true
|
|
11
|
+
VaultTree::Contract.new(@contract).vault_closed?('s_4').should be true
|
|
12
|
+
VaultTree::Contract.new(@contract).vault_closed?('s_5').should be true
|
|
9
13
|
end
|
|
10
14
|
|
|
11
|
-
When(/^I lock the
|
|
12
|
-
@contract = VaultTree::Contract.new(@
|
|
13
|
-
@contract = @contract.close_vault('message')
|
|
15
|
+
When(/^I lock away the shamir key share collection$/) do
|
|
16
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('share_collection')
|
|
14
17
|
end
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
@contract = VaultTree::Contract.new(@contract_json, external_data: @external_data)
|
|
18
|
-
@contract = @contract.close_vault('message')
|
|
19
|
+
Then(/^a random key is generated and split with the shamir secret sharing algorithm$/) do
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
Then(/^
|
|
22
|
-
@contract.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@contract.
|
|
22
|
+
Then(/^I can open the vault to recover the JSON representation of the secret shares$/) do
|
|
23
|
+
JSON.parse(VaultTree::Contract.new(@contract).open_vault('share_collection')).should be_an_instance_of(Hash)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
When(/^I fill an individual vault with the SECRET_SHARES keyword$/) do
|
|
27
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('share_1')
|
|
28
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('share_2')
|
|
29
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('share_3')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Then(/^the library takes the approprate share from the collection vault and locks it away$/) do
|
|
33
|
+
VaultTree::Contract.new(@contract).vault_closed?('share_1').should be true
|
|
34
|
+
VaultTree::Contract.new(@contract).vault_closed?('share_2').should be true
|
|
35
|
+
VaultTree::Contract.new(@contract).vault_closed?('share_3').should be true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
When(/^I close the key shares in their respective vaults$/) do
|
|
39
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('s_1')
|
|
40
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('s_2')
|
|
41
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('s_3')
|
|
42
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('s_4')
|
|
43
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('s_5')
|
|
27
44
|
end
|
|
28
45
|
|
|
29
|
-
|
|
30
|
-
@
|
|
46
|
+
Then(/^I can lock away a message with the key assembled from the shares$/) do
|
|
47
|
+
@message = 'MY SECRET STRING!'
|
|
48
|
+
@contract = VaultTree::Contract.new(@contract).close_vault('message', msg: @message)
|
|
31
49
|
end
|
|
32
50
|
|
|
33
|
-
Then(/^
|
|
34
|
-
|
|
35
|
-
@recovered_message.should == @external_data["message"]
|
|
51
|
+
Then(/^if all the shares are available I can unlock the message$/) do
|
|
52
|
+
VaultTree::Contract.new(@contract).open_vault('message').should == @message
|
|
36
53
|
end
|
data/lib/vault-tree.rb
CHANGED
|
@@ -10,7 +10,7 @@ require_relative 'vault-tree/util/string'
|
|
|
10
10
|
require_relative 'vault-tree/lock_smith'
|
|
11
11
|
|
|
12
12
|
# exceptions/*.rb
|
|
13
|
-
require_relative 'vault-tree/exceptions/
|
|
13
|
+
require_relative 'vault-tree/exceptions/library_exception'
|
|
14
14
|
VaultTree::PathHelpers.exceptions_files.each {|file| require_relative file }
|
|
15
15
|
|
|
16
16
|
# contract/*.rb
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module VaultTree
|
|
2
|
+
class ContentCiphertext
|
|
3
|
+
attr_reader :message, :vault_key
|
|
4
|
+
|
|
5
|
+
def initialize(c,k)
|
|
6
|
+
@message = c
|
|
7
|
+
@vault_key = k
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def evaluate
|
|
11
|
+
vault_key.asymmetric? ? asymmetric_ciphertext : symmetric_ciphertext
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def asymmetric_ciphertext
|
|
17
|
+
lock_smith.asymmetric_encrypt
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def symmetric_ciphertext
|
|
21
|
+
lock_smith.symmetric_encrypt
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def lock_smith
|
|
25
|
+
LockSmith.new(
|
|
26
|
+
public_key: vault_key.public,
|
|
27
|
+
private_key: vault_key.secret,
|
|
28
|
+
secret_key: vault_key.secret,
|
|
29
|
+
message: message
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module VaultTree
|
|
2
|
+
class ContentPlaintext
|
|
3
|
+
attr_reader :cipher_text, :vault_key
|
|
4
|
+
|
|
5
|
+
def initialize(c,k)
|
|
6
|
+
@cipher_text = c
|
|
7
|
+
@vault_key = k
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def evaluate
|
|
11
|
+
vault_key.asymmetric? ? asymmetric_plaintext : symmetric_plaintext
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def asymmetric_plaintext
|
|
17
|
+
lock_smith.asymmetric_decrypt
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def symmetric_plaintext
|
|
21
|
+
lock_smith.symmetric_decrypt
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def lock_smith
|
|
25
|
+
LockSmith.new(
|
|
26
|
+
public_key: vault_key.public,
|
|
27
|
+
private_key: vault_key.secret,
|
|
28
|
+
secret_key: vault_key.secret,
|
|
29
|
+
cipher_text: cipher_text
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -1,96 +1,39 @@
|
|
|
1
1
|
module VaultTree
|
|
2
2
|
class Contract
|
|
3
|
-
attr_reader :json
|
|
3
|
+
attr_reader :json, :contract_hash, :vault_list, :contract_header, :external_input
|
|
4
4
|
|
|
5
5
|
def initialize(json, params = {})
|
|
6
|
-
@
|
|
7
|
-
@
|
|
8
|
-
@
|
|
6
|
+
@contract_hash = Support::JSON.decode(json)
|
|
7
|
+
@contract_header = ContractHeader.new(contract_hash["header"])
|
|
8
|
+
@vault_list = VaultList.new(contract_hash["vaults"], self)
|
|
9
|
+
@external_input = {}
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
def close_vault(id,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
self
|
|
12
|
+
def close_vault(id, external_input = {data: nil})
|
|
13
|
+
@external_input = @external_input.merge(external_input)
|
|
14
|
+
@vault_list = vault_list.close_vault(id)
|
|
15
|
+
self.as_json
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
def open_vault(id, external_input = {})
|
|
19
|
+
@external_input = @external_input.merge(external_input)
|
|
20
|
+
vault_list.open_vault(id)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def vault_closed?(id)
|
|
24
|
-
|
|
24
|
+
vault_list.vault_closed?(id)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def header
|
|
28
|
-
|
|
28
|
+
contract_header.to_hash
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def vaults
|
|
32
|
-
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def vault(id)
|
|
36
|
-
id.nil? ? NullVault.new : Vault.new(id, vaults[id], self)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def update_vaults(vault)
|
|
40
|
-
@contract["vaults"][vault.id] = vault.properties unless vault.kind_of?(NullVault)
|
|
32
|
+
vault_list.to_hash
|
|
41
33
|
end
|
|
42
34
|
|
|
43
35
|
def as_json
|
|
44
36
|
ContractPresenter.new(self).as_json
|
|
45
37
|
end
|
|
46
|
-
|
|
47
|
-
def master_passphrase
|
|
48
|
-
validate_passphrase
|
|
49
|
-
@master_passphrase
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def external_data_hash
|
|
53
|
-
@external_data
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def external_data(id)
|
|
57
|
-
@external_data[id]
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
private
|
|
61
|
-
|
|
62
|
-
def passphrase_present?
|
|
63
|
-
!! @master_passphrase
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def valid_id?(id)
|
|
67
|
-
id.nil? || vaults.include?(id)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def non_empty_contents?(id)
|
|
71
|
-
! empty_contents?(id)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def empty_contents?(id)
|
|
75
|
-
vaults[id]['contents'].nil? || vaults[id]['contents'].empty?
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def contract
|
|
79
|
-
@contract ||= Support::JSON.decode(json)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def validate_vault(id)
|
|
83
|
-
raise Exceptions::VaultDoesNotExist unless valid_id?(id)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def validate_passphrase
|
|
87
|
-
raise Exceptions::MissingPassphrase unless passphrase_present?
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def update_external_data(params)
|
|
91
|
-
vault_id = params[:id]
|
|
92
|
-
data = params[:data]
|
|
93
|
-
@external_data = @external_data.merge({"#{vault_id}" => "#{data}"}) unless data.nil?
|
|
94
|
-
end
|
|
95
38
|
end
|
|
96
39
|
end
|