vault-tree 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +26 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +43 -0
- data/LICENSE.txt +22 -0
- data/README.md +118 -0
- data/Rakefile +17 -0
- data/VagrantFile +30 -0
- data/features/core.feature +44 -0
- data/features/exceptions.feature +41 -0
- data/features/steps/core.steps.rb +168 -0
- data/features/steps/exceptions.steps.rb +103 -0
- data/features/support/env.rb +1 -0
- data/features/world.rb +3 -0
- data/lib/vault-tree.rb +7 -0
- data/lib/vault-tree/config/dependencies.rb +4 -0
- data/lib/vault-tree/config/lib.rb +2 -0
- data/lib/vault-tree/config/path_helpers.rb +49 -0
- data/lib/vault-tree/config/string.rb +25 -0
- data/lib/vault-tree/contract/close_validator.rb +35 -0
- data/lib/vault-tree/contract/contract.rb +85 -0
- data/lib/vault-tree/contract/contract_presenter.rb +27 -0
- data/lib/vault-tree/contract/doorman.rb +112 -0
- data/lib/vault-tree/contract/null_vault.rb +16 -0
- data/lib/vault-tree/contract/open_validator.rb +20 -0
- data/lib/vault-tree/contract/vault.rb +96 -0
- data/lib/vault-tree/exceptions/empty_vault.rb +8 -0
- data/lib/vault-tree/exceptions/fill_attempt_master_password.rb +6 -0
- data/lib/vault-tree/exceptions/invalid_signature.rb +0 -0
- data/lib/vault-tree/exceptions/malformed_json.rb +0 -0
- data/lib/vault-tree/exceptions/missing_external_data.rb +6 -0
- data/lib/vault-tree/exceptions/missing_partner_decryption_key.rb +6 -0
- data/lib/vault-tree/exceptions/missing_passphrase.rb +6 -0
- data/lib/vault-tree/exceptions/non_unique_vault_id.rb +0 -0
- data/lib/vault-tree/exceptions/unsupported_keyword.rb +6 -0
- data/lib/vault-tree/exceptions/vault_does_not_exist.rb +6 -0
- data/lib/vault-tree/exceptions/vault_tree_exception.rb +6 -0
- data/lib/vault-tree/keywords/decryption_key.rb +14 -0
- data/lib/vault-tree/keywords/external_data.rb +13 -0
- data/lib/vault-tree/keywords/keyword.rb +19 -0
- data/lib/vault-tree/keywords/keyword_interpreter.rb +45 -0
- data/lib/vault-tree/keywords/master_passphrase.rb +9 -0
- data/lib/vault-tree/keywords/public_encryption_key.rb +27 -0
- data/lib/vault-tree/keywords/random_number.rb +9 -0
- data/lib/vault-tree/keywords/shared_key.rb +24 -0
- data/lib/vault-tree/keywords/unlocked.rb +9 -0
- data/lib/vault-tree/keywords/vault_contents.rb +13 -0
- data/lib/vault-tree/lock_smith/asymmetric_cipher.rb +31 -0
- data/lib/vault-tree/lock_smith/crypto_hash.rb +11 -0
- data/lib/vault-tree/lock_smith/digital_signature.rb +32 -0
- data/lib/vault-tree/lock_smith/encryption_key_pair.rb +25 -0
- data/lib/vault-tree/lock_smith/null_vault.rb +4 -0
- data/lib/vault-tree/lock_smith/random_number.rb +11 -0
- data/lib/vault-tree/lock_smith/shared_key_pair.rb +12 -0
- data/lib/vault-tree/lock_smith/signing_key_pair.rb +25 -0
- data/lib/vault-tree/lock_smith/symmetric_cipher.rb +25 -0
- data/lib/vault-tree/util/json.rb +16 -0
- data/lib/vault-tree/version.rb +3 -0
- data/spec/app/locksmith/asymmetric_cipher_spec.rb +25 -0
- data/spec/app/locksmith/signing_key_pair_spec.rb +22 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/fixtures/blank_simple_test_contract.json +14 -0
- data/spec/support/fixtures/broken_contract.json +55 -0
- data/spec/support/fixtures/one_two_three-0.5.0.EXP.json +105 -0
- data/spec/support/fixtures/reference_contract.1.0.0.json +227 -0
- data/spec/support/fixtures/simple_test_contract.json +14 -0
- data/support/cookbooks/ark/.gitignore +12 -0
- data/support/cookbooks/ark/.kitchen.yml +34 -0
- data/support/cookbooks/ark/.travis.yml +6 -0
- data/support/cookbooks/ark/Berksfile +9 -0
- data/support/cookbooks/ark/CHANGELOG.md +87 -0
- data/support/cookbooks/ark/CONTRIBUTING.md +257 -0
- data/support/cookbooks/ark/README.md +301 -0
- data/support/cookbooks/ark/Rakefile +36 -0
- data/support/cookbooks/ark/TESTING.md +25 -0
- data/support/cookbooks/ark/Toftfile +15 -0
- data/support/cookbooks/ark/attributes/default.rb +6 -0
- data/support/cookbooks/ark/chefignore +96 -0
- 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 +94 -0
- data/support/cookbooks/ark/libraries/default.rb +167 -0
- data/support/cookbooks/ark/metadata.rb +13 -0
- data/support/cookbooks/ark/providers/default.rb +370 -0
- data/support/cookbooks/ark/recipes/default.rb +31 -0
- data/support/cookbooks/ark/recipes/test.rb +138 -0
- data/support/cookbooks/ark/resources/default.rb +54 -0
- data/support/cookbooks/ark/templates/default/add_to_path.sh.erb +1 -0
- data/support/cookbooks/ark/test/support/Gemfile +4 -0
- data/support/cookbooks/build-essential/README.md +24 -0
- data/support/cookbooks/build-essential/metadata.rb +10 -0
- data/support/cookbooks/build-essential/recipes/default.rb +45 -0
- data/support/cookbooks/chruby/.gitignore +15 -0
- data/support/cookbooks/chruby/.kitchen.yml +26 -0
- data/support/cookbooks/chruby/.ruby_version +1 -0
- data/support/cookbooks/chruby/Berksfile +3 -0
- data/support/cookbooks/chruby/Gemfile +7 -0
- data/support/cookbooks/chruby/LICENSE +14 -0
- data/support/cookbooks/chruby/README.md +92 -0
- data/support/cookbooks/chruby/Rakefile +7 -0
- data/support/cookbooks/chruby/Thorfile +6 -0
- data/support/cookbooks/chruby/Vagrantfile +86 -0
- data/support/cookbooks/chruby/attributes/default.rb +10 -0
- data/support/cookbooks/chruby/chefignore +96 -0
- data/support/cookbooks/chruby/metadata.rb +11 -0
- data/support/cookbooks/chruby/recipes/default.rb +43 -0
- data/support/cookbooks/chruby/recipes/system.rb +25 -0
- data/support/cookbooks/chruby/templates/default/chruby.sh.erb +22 -0
- data/support/cookbooks/chruby/test/integration/default/bash/embedded_test.sh +1 -0
- data/support/cookbooks/git/.gitignore +14 -0
- data/support/cookbooks/git/.kitchen.yml +46 -0
- data/support/cookbooks/git/Berksfile +8 -0
- data/support/cookbooks/git/CHANGELOG.md +87 -0
- data/support/cookbooks/git/CONTRIBUTING +29 -0
- data/support/cookbooks/git/Gemfile +3 -0
- data/support/cookbooks/git/LICENSE +201 -0
- data/support/cookbooks/git/README.md +115 -0
- data/support/cookbooks/git/TESTING.md +25 -0
- data/support/cookbooks/git/attributes/default.rb +40 -0
- data/support/cookbooks/git/metadata.rb +35 -0
- data/support/cookbooks/git/recipes/default.rb +53 -0
- data/support/cookbooks/git/recipes/server.rb +58 -0
- data/support/cookbooks/git/recipes/source.rb +49 -0
- data/support/cookbooks/git/recipes/windows.rb +37 -0
- data/support/cookbooks/git/templates/default/git-xinetd.d.erb +10 -0
- data/support/cookbooks/git/templates/default/sv-git-daemon-log-run.erb +2 -0
- data/support/cookbooks/git/templates/default/sv-git-daemon-run.erb +3 -0
- data/support/cookbooks/install_ruby/README.md +3 -0
- data/support/cookbooks/install_ruby/metadata.rb +10 -0
- data/support/cookbooks/install_ruby/recipes/default.rb +14 -0
- data/support/cookbooks/ruby_build/.gitignore +6 -0
- data/support/cookbooks/ruby_build/.kitchen.yml +31 -0
- data/support/cookbooks/ruby_build/.travis.yml +4 -0
- data/support/cookbooks/ruby_build/Berksfile +10 -0
- data/support/cookbooks/ruby_build/CHANGELOG.md +72 -0
- data/support/cookbooks/ruby_build/Gemfile +14 -0
- data/support/cookbooks/ruby_build/README.md +338 -0
- data/support/cookbooks/ruby_build/Rakefile +21 -0
- data/support/cookbooks/ruby_build/attributes/default.rb +67 -0
- data/support/cookbooks/ruby_build/chefignore +53 -0
- data/support/cookbooks/ruby_build/libraries/ruby_build_recipe_helpers.rb +40 -0
- data/support/cookbooks/ruby_build/metadata.rb +18 -0
- data/support/cookbooks/ruby_build/providers/ruby.rb +88 -0
- data/support/cookbooks/ruby_build/recipes/default.rb +69 -0
- data/support/cookbooks/ruby_build/resources/ruby.rb +33 -0
- data/support/cookbooks/ruby_build/test/cookbooks/alltherubies/metadata.rb +10 -0
- data/support/cookbooks/ruby_build/test/cookbooks/alltherubies/recipes/default.rb +59 -0
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/_verify_tests.bash +33 -0
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_1.8.7.bats +29 -0
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_1.9.2.bats +18 -0
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_1.9.3.bats +18 -0
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_2.0.0.bats +18 -0
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_jruby.bats +20 -0
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_rbx.bats +18 -0
- data/support/cookbooks/ruby_build/test/integration/alltherubies/bats/verify_ree.bats +19 -0
- data/support/cookbooks/ruby_build/test/integration/installation/bats/installation.bats +6 -0
- data/support/scripts/libsodium_ubuntu.sh +80 -0
- data/support/tasks/.gitkeep +0 -0
- data/support/tasks/libsodium_install.rb +57 -0
- data/vault-tree.gemspec +26 -0
- metadata +305 -0
@@ -0,0 +1,103 @@
|
|
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('alice_contract_secret')
|
10
|
+
rescue => e
|
11
|
+
@exception = e
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Then(/^a MissingPassphrase exception is raised$/) do
|
16
|
+
@exception.should be_an_instance_of(VaultTree::Exceptions::MissingPassphrase)
|
17
|
+
end
|
18
|
+
|
19
|
+
Given(/^the broken contract$/) do
|
20
|
+
contract_path = VaultTree::PathHelpers.broken_contract
|
21
|
+
@contract_json = File.read(contract_path)
|
22
|
+
@contract = VaultTree::Contract.new(@contract_json, master_passphrase: 'TEST_USER', external_data: {})
|
23
|
+
end
|
24
|
+
|
25
|
+
When(/^I attempt fill a vault with External Data that does not exists$/) do
|
26
|
+
begin
|
27
|
+
@contract = @contract.close_vault('missing_external_data_vault')
|
28
|
+
rescue => e
|
29
|
+
@exception = e
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Then(/^a MissingExternalData exception is raised$/) do
|
34
|
+
@exception.should be_an_instance_of(VaultTree::Exceptions::MissingExternalData)
|
35
|
+
end
|
36
|
+
|
37
|
+
When(/^I attempt fill a vault with my Master Password$/) do
|
38
|
+
begin
|
39
|
+
@contract = @contract.close_vault('fill_with_master_pass_vault')
|
40
|
+
rescue => e
|
41
|
+
@exception = e
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
Then(/^a FillAttemptMasterPassword exception is raised$/) do
|
46
|
+
@exception.should be_an_instance_of(VaultTree::Exceptions::FillAttemptMasterPassword)
|
47
|
+
end
|
48
|
+
|
49
|
+
When(/^I attempt to open an empty vault$/) do
|
50
|
+
begin
|
51
|
+
@contents = @contract.retrieve_contents('empty_vault')
|
52
|
+
rescue => e
|
53
|
+
@exception = e
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
Then(/^an EmptyVault exception is raised$/) do
|
58
|
+
@exception.should be_an_instance_of(VaultTree::Exceptions::EmptyVault)
|
59
|
+
end
|
60
|
+
|
61
|
+
When(/^I attempt to open a vault that does not exists$/) do
|
62
|
+
begin
|
63
|
+
@contents = @contract.retrieve_contents('non_existant_vault')
|
64
|
+
rescue => e
|
65
|
+
@exception = e
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
When(/^I attempt to close a vault that does not exists$/) do
|
70
|
+
begin
|
71
|
+
@contents = @contract.close_vault('non_existant_vault')
|
72
|
+
rescue => e
|
73
|
+
@exception = e
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
Then(/^a VaultDoesNotExist exception is raised$/) do
|
78
|
+
@exception.should be_an_instance_of(VaultTree::Exceptions::VaultDoesNotExist)
|
79
|
+
end
|
80
|
+
|
81
|
+
When(/^I attempt fill a vault with an unsupported Keyword$/) do
|
82
|
+
begin
|
83
|
+
@contract = @contract.close_vault('unsupported_keyword')
|
84
|
+
rescue => e
|
85
|
+
@exception = e
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Then(/^an UnsupportedKeyword exception is raised$/) do
|
90
|
+
@exception.should be_an_instance_of(VaultTree::Exceptions::UnsupportedKeyword)
|
91
|
+
end
|
92
|
+
|
93
|
+
When(/^I attempt to fill with an encryption key without first establishing the decryption key$/) do
|
94
|
+
begin
|
95
|
+
@contract = @contract.close_vault('orphaned_public_key')
|
96
|
+
rescue => e
|
97
|
+
@exception = e
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
Then(/^a MissingPartnerDecryptionKey exception is raised$/) do
|
102
|
+
@exception.should be_an_instance_of(VaultTree::Exceptions::MissingPartnerDecryptionKey)
|
103
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative '../../lib/vault-tree'
|
data/features/world.rb
ADDED
data/lib/vault-tree.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# require_relative - Ruby > 1.9 method
|
2
|
+
# require_rel - 'gem require_all' helper method to require all relative
|
3
|
+
|
4
|
+
require_relative 'vault-tree/config/dependencies'
|
5
|
+
require_relative 'vault-tree/config/path_helpers'
|
6
|
+
require_relative 'vault-tree/config/string'
|
7
|
+
require_relative 'vault-tree/config/lib'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module VaultTree
|
2
|
+
module PathHelpers
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def current_dir
|
6
|
+
File.dirname(__FILE__)
|
7
|
+
end
|
8
|
+
|
9
|
+
def walk_to_root
|
10
|
+
'../../../'
|
11
|
+
end
|
12
|
+
|
13
|
+
def project_dir
|
14
|
+
File.expand_path(project_dir_rel)
|
15
|
+
end
|
16
|
+
|
17
|
+
def project_dir_rel
|
18
|
+
File.join(current_dir,walk_to_root)
|
19
|
+
end
|
20
|
+
|
21
|
+
def app_dir
|
22
|
+
lib_dir
|
23
|
+
end
|
24
|
+
|
25
|
+
def lib_dir
|
26
|
+
"#{project_dir}/lib"
|
27
|
+
end
|
28
|
+
|
29
|
+
def fixtures_dir
|
30
|
+
"#{project_dir}/spec/support/fixtures"
|
31
|
+
end
|
32
|
+
|
33
|
+
def reference_contract
|
34
|
+
"#{fixtures_dir}/reference_contract.1.0.0.json"
|
35
|
+
end
|
36
|
+
|
37
|
+
def broken_contract
|
38
|
+
"#{fixtures_dir}/broken_contract.json"
|
39
|
+
end
|
40
|
+
|
41
|
+
def blank_simple_test_contract
|
42
|
+
"#{fixtures_dir}/blank_simple_test_contract.json"
|
43
|
+
end
|
44
|
+
|
45
|
+
def simple_test_contract
|
46
|
+
"#{fixtures_dir}/simple_test_contract.json"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class String
|
2
|
+
def compress
|
3
|
+
gsub("\n", '').squeeze(' ').strip
|
4
|
+
end
|
5
|
+
|
6
|
+
def extract_ancestor_id
|
7
|
+
self.gsub(/(CONTENTS\[\')|(\'\])/,'').strip
|
8
|
+
end
|
9
|
+
|
10
|
+
def checksum
|
11
|
+
Digest::SHA1.hexdigest(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
def non_empty?
|
15
|
+
! self.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
def camelize
|
19
|
+
self.split("_").each {|s| s.capitalize! }.join("")
|
20
|
+
end
|
21
|
+
|
22
|
+
def has_ancestor?
|
23
|
+
self.include? 'CONTENTS'
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module VaultTree
|
2
|
+
class CloseValidator
|
3
|
+
attr_reader :vault
|
4
|
+
|
5
|
+
def initialize(vault)
|
6
|
+
@vault = vault
|
7
|
+
end
|
8
|
+
|
9
|
+
def validate!
|
10
|
+
confirm_valid_fill_keyword
|
11
|
+
validate_external_data
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def confirm_valid_fill_keyword
|
18
|
+
raise Exceptions::FillAttemptMasterPassword if vault.fill_with == 'MASTER_PASSPHRASE'
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate_external_data
|
22
|
+
if external_data_required? && external_data_missing?
|
23
|
+
raise Exceptions::MissingExternalData
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def external_data_required?
|
28
|
+
vault.fill_with == 'EXTERNAL_DATA'
|
29
|
+
end
|
30
|
+
|
31
|
+
def external_data_missing?
|
32
|
+
vault.contract.external_data(vault.id).nil?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module VaultTree
|
2
|
+
class Contract
|
3
|
+
attr_reader :json
|
4
|
+
|
5
|
+
def initialize(json, params = {})
|
6
|
+
@json = json
|
7
|
+
@master_passphrase = params[:master_passphrase]
|
8
|
+
@external_data = params[:external_data]
|
9
|
+
end
|
10
|
+
|
11
|
+
def close_vault(id)
|
12
|
+
validate_vault(id)
|
13
|
+
update_vaults vault(id).close
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def retrieve_contents(id)
|
18
|
+
validate_vault(id)
|
19
|
+
vault(id).retrieve_contents
|
20
|
+
end
|
21
|
+
|
22
|
+
def vault_closed?(id)
|
23
|
+
non_empty_contents?(id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def header
|
27
|
+
contract["header"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def vaults
|
31
|
+
contract["vaults"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def vault(id)
|
35
|
+
id.nil? ? NullVault.new : Vault.new(id, vaults[id], self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_vaults(vault)
|
39
|
+
@contract["vaults"][vault.id] = vault.properties unless vault.kind_of?(NullVault)
|
40
|
+
end
|
41
|
+
|
42
|
+
def as_json
|
43
|
+
ContractPresenter.new(self).as_json
|
44
|
+
end
|
45
|
+
|
46
|
+
def master_passphrase
|
47
|
+
validate_passphrase
|
48
|
+
@master_passphrase
|
49
|
+
end
|
50
|
+
|
51
|
+
def external_data(id)
|
52
|
+
@external_data[id]
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def passphrase_present?
|
58
|
+
!! @master_passphrase
|
59
|
+
end
|
60
|
+
|
61
|
+
def valid_id?(id)
|
62
|
+
id.nil? || vaults.include?(id)
|
63
|
+
end
|
64
|
+
|
65
|
+
def non_empty_contents?(id)
|
66
|
+
! empty_contents?(id)
|
67
|
+
end
|
68
|
+
|
69
|
+
def empty_contents?(id)
|
70
|
+
vaults[id]['contents'].nil? || vaults[id]['contents'].empty?
|
71
|
+
end
|
72
|
+
|
73
|
+
def contract
|
74
|
+
@contract ||= Support::JSON.decode(json)
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate_vault(id)
|
78
|
+
raise Exceptions::VaultDoesNotExist unless valid_id?(id)
|
79
|
+
end
|
80
|
+
|
81
|
+
def validate_passphrase
|
82
|
+
raise Exceptions::MissingPassphrase unless passphrase_present?
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module VaultTree
|
2
|
+
class ContractPresenter
|
3
|
+
attr_reader :contract
|
4
|
+
|
5
|
+
def initialize(contract)
|
6
|
+
@contract = contract
|
7
|
+
end
|
8
|
+
|
9
|
+
def as_json
|
10
|
+
JSON.pretty_generate(contract_hash)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def contract_hash
|
16
|
+
{header: contract_header, vaults: contract_vaults}
|
17
|
+
end
|
18
|
+
|
19
|
+
def contract_header
|
20
|
+
contract.header
|
21
|
+
end
|
22
|
+
|
23
|
+
def contract_vaults
|
24
|
+
contract.vaults
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module VaultTree
|
2
|
+
class Vault
|
3
|
+
class Doorman
|
4
|
+
attr_reader :vault
|
5
|
+
|
6
|
+
def initialize(vault)
|
7
|
+
@vault = vault
|
8
|
+
end
|
9
|
+
|
10
|
+
def locked_contents
|
11
|
+
CloseValidator.new(vault).validate!
|
12
|
+
already_locked? ? contents : ciphertext_contents
|
13
|
+
end
|
14
|
+
|
15
|
+
def unlocked_contents
|
16
|
+
OpenValidator.new(vault).validate!
|
17
|
+
plaintext_contents
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def ciphertext_contents
|
23
|
+
shared_locking_key? ? asymmetric_ciphertext : symmetric_ciphertext
|
24
|
+
end
|
25
|
+
|
26
|
+
def plaintext_contents
|
27
|
+
shared_unlocking_key? ? asymmetric_plaintext : symmetric_plaintext
|
28
|
+
end
|
29
|
+
|
30
|
+
def asymmetric_ciphertext
|
31
|
+
asymmetric_cipher.encrypt(public_key: locking_public_key, secret_key: locking_secret_key, plain_text: filler)
|
32
|
+
end
|
33
|
+
|
34
|
+
def asymmetric_plaintext
|
35
|
+
asymmetric_cipher.decrypt(public_key: unlocking_public_key, secret_key: unlocking_secret_key, cipher_text: contents)
|
36
|
+
end
|
37
|
+
|
38
|
+
def symmetric_ciphertext
|
39
|
+
symmetric_cipher.encrypt(key: locking_key, plain_text: filler)
|
40
|
+
end
|
41
|
+
|
42
|
+
def symmetric_plaintext
|
43
|
+
symmetric_cipher.decrypt(key: unlocking_key, cipher_text: contents)
|
44
|
+
end
|
45
|
+
|
46
|
+
def locking_key
|
47
|
+
vault.locking_key
|
48
|
+
end
|
49
|
+
|
50
|
+
def unlocking_key
|
51
|
+
vault.unlocking_key
|
52
|
+
end
|
53
|
+
|
54
|
+
def locking_public_key
|
55
|
+
locking_key_pair.public_key
|
56
|
+
end
|
57
|
+
|
58
|
+
def locking_secret_key
|
59
|
+
locking_key_pair.secret_key
|
60
|
+
end
|
61
|
+
|
62
|
+
def unlocking_public_key
|
63
|
+
unlocking_key_pair.public_key
|
64
|
+
end
|
65
|
+
|
66
|
+
def unlocking_secret_key
|
67
|
+
unlocking_key_pair.secret_key
|
68
|
+
end
|
69
|
+
|
70
|
+
def locking_key_pair
|
71
|
+
vault.locking_key if shared_locking_key?
|
72
|
+
end
|
73
|
+
|
74
|
+
def unlocking_key_pair
|
75
|
+
vault.unlocking_key if shared_unlocking_key?
|
76
|
+
end
|
77
|
+
|
78
|
+
def empty?
|
79
|
+
vault.empty?
|
80
|
+
end
|
81
|
+
|
82
|
+
def already_locked?
|
83
|
+
! empty?
|
84
|
+
end
|
85
|
+
|
86
|
+
def filler
|
87
|
+
vault.filler
|
88
|
+
end
|
89
|
+
|
90
|
+
def contents
|
91
|
+
vault.contents
|
92
|
+
end
|
93
|
+
|
94
|
+
def shared_locking_key?
|
95
|
+
vault.lock_with =~ /SHARED_KEY/
|
96
|
+
end
|
97
|
+
|
98
|
+
def shared_unlocking_key?
|
99
|
+
vault.unlock_with =~ /SHARED_KEY/
|
100
|
+
end
|
101
|
+
|
102
|
+
def asymmetric_cipher
|
103
|
+
LockSmith::AsymmetricCipher.new
|
104
|
+
end
|
105
|
+
|
106
|
+
def symmetric_cipher
|
107
|
+
LockSmith::SymmetricCipher.new
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|