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
|
@@ -4,9 +4,7 @@ Now that we've explored the ideas of a **Contract**, **Contract Enforcement**, a
|
|
|
4
4
|
|
|
5
5
|
#### Vaults
|
|
6
6
|
|
|
7
|
-
Vault Tree Contracts are made by assembling simple structures called **Vaults**.
|
|
8
|
-
|
|
9
|
-
A vault is like a digital lock box that stores a single unambiguous piece of information. This piece of information is needed to continue the execution of a contract beyond a certain event.
|
|
7
|
+
Vault Tree Contracts are made by assembling simple structures called **Vaults**. A vault is like a digital lock box that stores a single unambiguous piece of information.
|
|
10
8
|
|
|
11
9
|
The light bulb should turn on when you realize that vaults can hold not only valuable external information, but the **keys to other vaults**.
|
|
12
10
|
|
|
@@ -21,6 +19,10 @@ benefit of being a **Distributed Cryptographic Contract**. This means:
|
|
|
21
19
|
* Each Vault encrypts a piece of secret information. This can be external
|
|
22
20
|
information such as a _URL_ or a _Bitcoin Wallet Address_. More often, a vault will contain the unlocking key to another vault in the contract.
|
|
23
21
|
* The way in which the contract author **chooses to structure** the releationship between vaults, will determine how the contract is **Enforced**.
|
|
22
|
+
* It is the responsibility of the contract author to arrange vaults so that there are no contract [moral hazards] or [perverse incentives].
|
|
23
|
+
|
|
24
|
+
[moral hazards]: http://en.wikipedia.org/wiki/Moral_hazard
|
|
25
|
+
[perverse incentives]: http://en.wikipedia.org/wiki/Perverse_incentive
|
|
24
26
|
|
|
25
27
|
#### Complete Contracts
|
|
26
28
|
|
|
@@ -50,34 +52,29 @@ arranged to enforce the terms of the contract.
|
|
|
50
52
|
Let's take a look at an example vault:
|
|
51
53
|
|
|
52
54
|
```javascript
|
|
53
|
-
"
|
|
55
|
+
"bob_random_key": {
|
|
54
56
|
"fill_with": "RANDOM_NUMBER",
|
|
55
|
-
"lock_with": "KEY['
|
|
56
|
-
"unlock_with": "KEY['
|
|
57
|
-
"contents": "
|
|
57
|
+
"lock_with": "KEY['bob_first_vault_key']",
|
|
58
|
+
"unlock_with": "KEY['alice_third_vault_key']",
|
|
59
|
+
"contents": "dc92c330e5f911e3ac100800200c9a6648ab522cf91739ade ... "
|
|
58
60
|
}
|
|
59
61
|
```
|
|
60
62
|
|
|
61
|
-
It's important to keep in mind that, **every** vault follows this format. This
|
|
63
|
+
It's important to keep in mind that, **every** vault follows this format. This
|
|
64
|
+
convention for representing a vault should be sufficient to build any type of
|
|
65
|
+
simple or sophisticated contract.
|
|
62
66
|
|
|
63
67
|
#### Vault Id
|
|
64
68
|
|
|
65
|
-
The **Vault Id** can be thought of as both the name and the **
|
|
69
|
+
The **Vault Id** can be thought of as both the name and the **unique** identifier of the vault.
|
|
66
70
|
|
|
67
71
|
In this case we have:
|
|
68
72
|
|
|
69
73
|
```
|
|
70
|
-
"
|
|
74
|
+
"bob_random_key"
|
|
71
75
|
```
|
|
72
76
|
|
|
73
|
-
Try to give meaningful names that give insight into the locked contents held within the vault.
|
|
74
|
-
|
|
75
|
-
A vault owner is the contract party that is responsibily for filling and locking the vault. In this simple case we have **bob**, but in an employment contract for example, we may have vault owners named **employer** and **employee**.
|
|
76
|
-
|
|
77
|
-
It is the responsibility of the contract author to assign vault owners in such a way that there are no contract [moral hazards] or [perverse incentives].
|
|
78
|
-
|
|
79
|
-
[moral hazards]: http://en.wikipedia.org/wiki/Moral_hazard
|
|
80
|
-
[perverse incentives]: http://en.wikipedia.org/wiki/Perverse_incentive
|
|
77
|
+
Try to give meaningful names that give insight into the locked contents held within the vault.
|
|
81
78
|
|
|
82
79
|
#### Fill With
|
|
83
80
|
|
|
@@ -103,25 +100,23 @@ The **unlock_with** field naturally identifies the source of the vault's **Unloc
|
|
|
103
100
|
|
|
104
101
|
It may not be obvious, but the reference to the Unlocking key does not necessarily need to be the same as the reference to the **Locking Key**. Here are some examples of where this could be the case:
|
|
105
102
|
|
|
106
|
-
* The same key is used to lock and unlock the vault, but copies of this key are
|
|
107
|
-
* held in two separate vaults. Take a look at the **Block Chain Key Transfer**
|
|
108
|
-
* contract to see a good example of this.
|
|
103
|
+
* The same key is used to lock and unlock the vault, but copies of this key are held in two separate vaults. Take a look at the **Block Chain Key Transfer** contract to see a good example of this.
|
|
109
104
|
* Vault Tree supports the notion of an **Asymmetric Vault** through the _DSL Keyword_
|
|
110
105
|
|
|
111
106
|
```
|
|
112
107
|
DH_KEY
|
|
113
108
|
```
|
|
114
109
|
|
|
115
|
-
An Asymmetric Vault is locked and unlocked with the help of a [Public-Private](http://en.wikipedia.org/wiki/Public-key_cryptography) keypair. Vault Tree's underlying cryptographic library makes this possible by implementing a cutting edge variant of the [ECDH] key exchange protocol.
|
|
110
|
+
An Asymmetric Vault is locked and unlocked with the help of a [Public-Private](http://en.wikipedia.org/wiki/Public-key_cryptography) keypair. Vault Tree's underlying cryptographic library makes this possible by implementing a cutting edge variant of the [ECDH] key exchange protocol.
|
|
116
111
|
|
|
117
112
|
[ECDH]: http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman
|
|
118
113
|
|
|
119
114
|
#### Contents
|
|
120
115
|
|
|
121
|
-
As you would expect, this field references the encrypted contents of the vault. In the example above you can see the
|
|
116
|
+
As you would expect, this field references the encrypted contents of the vault. In the example above you can see the _Hex_ encoded ciphertext:
|
|
122
117
|
|
|
123
118
|
```
|
|
124
|
-
"contents": "
|
|
119
|
+
"contents": "dc92c330e5f911e3ac100800200c9a6648ab522cf91739ade ... "
|
|
125
120
|
```
|
|
126
121
|
Here are some items to keep in mind:
|
|
127
122
|
|
data/features/decision_tree.md
CHANGED
|
@@ -7,7 +7,7 @@ Contracts can be modeled as a [Decision Tree]. Intuitively this means that:
|
|
|
7
7
|
* **Events** are represented as nodes in the graph, **Outcomes** are events that correspond to [Leaf Nodes].
|
|
8
8
|
* Once a contract has been **Negotiated**, contract execution proceeds down the graph beginning at the [Root Node].
|
|
9
9
|
* Edges in the graph correspond to real world conditions that must be met before making a valid trasition between two events.
|
|
10
|
-
* **Well Written** contracts
|
|
10
|
+
* **Well Written** contracts correspond to well structured graphs.
|
|
11
11
|
|
|
12
12
|
[Directed Graph]: http://en.wikipedia.org/wiki/Directed_graph
|
|
13
13
|
[Tree]: http://en.wikipedia.org/wiki/Tree_%28graph_theory%29
|
data/features/exceptions.feature
CHANGED
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
Feature: Vault Tree Exceptions
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Then an EmptyVault exception is raised
|
|
3
|
+
The library trys to anticipate common usage errors. A
|
|
4
|
+
custom error with a helpful message should be raised if there
|
|
5
|
+
is a problem with you contract.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Then a FillAttemptMasterPassword exception is raised
|
|
7
|
+
If you do run across an unexpected ruby runtime error, please
|
|
8
|
+
file a Github issue. I want to make the experience of executing
|
|
9
|
+
and debugging your own contracts as painless as possible.
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
Given the broken contract
|
|
15
|
-
When I attempt fill a vault with External Data that does not exists
|
|
16
|
-
Then a MissingExternalData exception is raised
|
|
11
|
+
Thanks!
|
|
17
12
|
|
|
18
|
-
Scenario:
|
|
13
|
+
Scenario: Unsupported Keyword
|
|
19
14
|
Given this broken contract:
|
|
20
15
|
"""javascript
|
|
21
16
|
{
|
|
22
17
|
"header": {},
|
|
23
18
|
"vaults": {
|
|
24
|
-
"
|
|
25
|
-
"fill_with": "
|
|
19
|
+
"unsupported_keyword":{
|
|
20
|
+
"fill_with": "UNSUPPORTED_KEYWORD",
|
|
26
21
|
"lock_with": "UNLOCKED",
|
|
27
22
|
"unlock_with": "UNLOCKED",
|
|
28
23
|
"contents": ""
|
|
@@ -30,63 +25,79 @@ Scenario: Missing External Data On Lock
|
|
|
30
25
|
}
|
|
31
26
|
}
|
|
32
27
|
"""
|
|
33
|
-
When I attempt
|
|
34
|
-
Then
|
|
28
|
+
When I attempt fill a vault with an unsupported Keyword
|
|
29
|
+
Then an UnsupportedKeyword exception is raised
|
|
35
30
|
|
|
36
|
-
Scenario:
|
|
31
|
+
Scenario: Vault Does Not Exists on Retrieval
|
|
37
32
|
Given this broken contract:
|
|
38
33
|
"""javascript
|
|
39
34
|
{
|
|
40
35
|
"header": {},
|
|
41
36
|
"vaults": {
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
|
|
38
|
+
"empty_vault":{
|
|
44
39
|
"fill_with": "RANDOM_NUMBER",
|
|
45
|
-
"lock_with": "
|
|
46
|
-
"unlock_with": "
|
|
40
|
+
"lock_with": "UNLOCKED",
|
|
41
|
+
"unlock_with": "UNLOCKED",
|
|
47
42
|
"contents": ""
|
|
48
43
|
}
|
|
49
44
|
}
|
|
50
45
|
}
|
|
51
46
|
"""
|
|
52
|
-
When I lock the data away
|
|
53
|
-
And I attempt to unlock a vault with External Data that does not exists
|
|
54
|
-
Then a MissingExternalData exception is raised
|
|
55
|
-
|
|
56
|
-
Scenario: Unsupported Keyword
|
|
57
|
-
Given the broken contract
|
|
58
|
-
When I attempt fill a vault with an unsupported Keyword
|
|
59
|
-
Then an UnsupportedKeyword exception is raised
|
|
60
|
-
|
|
61
|
-
Scenario: Vault Does Not Exists on Retrieval
|
|
62
|
-
Given the broken contract
|
|
63
47
|
When I attempt to open a vault that does not exists
|
|
64
48
|
Then a VaultDoesNotExist exception is raised
|
|
65
49
|
|
|
66
50
|
Scenario: Vault Does Not Exists on Closing
|
|
67
|
-
Given
|
|
51
|
+
Given this broken contract:
|
|
52
|
+
"""javascript
|
|
53
|
+
{
|
|
54
|
+
"header": {},
|
|
55
|
+
"vaults": {
|
|
56
|
+
|
|
57
|
+
"empty_vault":{
|
|
58
|
+
"fill_with": "RANDOM_NUMBER",
|
|
59
|
+
"lock_with": "UNLOCKED",
|
|
60
|
+
"unlock_with": "UNLOCKED",
|
|
61
|
+
"contents": ""
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
"""
|
|
68
66
|
When I attempt to close a vault that does not exists
|
|
69
67
|
Then a VaultDoesNotExist exception is raised
|
|
70
68
|
|
|
71
|
-
Scenario: Missing Partner Decryption Key
|
|
72
|
-
Given the broken contract
|
|
73
|
-
When I attempt to fill with an encryption key without first establishing the decryption key
|
|
74
|
-
Then a MissingPartnerDecryptionKey exception is raised
|
|
75
|
-
|
|
76
69
|
Scenario: Failed Symmetric Unlock Attempt
|
|
77
70
|
Given this broken contract:
|
|
78
71
|
"""javascript
|
|
79
72
|
{
|
|
80
73
|
"header": {},
|
|
81
74
|
"vaults": {
|
|
82
|
-
"
|
|
75
|
+
"some_random_vault":{
|
|
83
76
|
"fill_with": "RANDOM_NUMBER",
|
|
84
|
-
"lock_with": "
|
|
85
|
-
"unlock_with": "
|
|
77
|
+
"lock_with": "EXTERNAL_INPUT['right_secret']",
|
|
78
|
+
"unlock_with": "EXTERNAL_INPUT['wrong_secret']",
|
|
86
79
|
"contents": ""
|
|
87
80
|
}
|
|
88
81
|
}
|
|
89
82
|
}
|
|
90
83
|
"""
|
|
91
|
-
When I lock a vault with External
|
|
84
|
+
When I lock a vault with External Input and attempt to unlock with the wrong External Input
|
|
92
85
|
Then a FailedUnlockAttempt exception is raised
|
|
86
|
+
|
|
87
|
+
Scenario: Missing External Input On Lock
|
|
88
|
+
Given this broken contract:
|
|
89
|
+
"""javascript
|
|
90
|
+
{
|
|
91
|
+
"header": {},
|
|
92
|
+
"vaults": {
|
|
93
|
+
"missing_external_input_vault":{
|
|
94
|
+
"fill_with": "EXTERNAL_INPUT['empty_value']",
|
|
95
|
+
"lock_with": "UNLOCKED",
|
|
96
|
+
"unlock_with": "UNLOCKED",
|
|
97
|
+
"contents": ""
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
"""
|
|
102
|
+
When I attempt lock a vault with External Input that does not exists
|
|
103
|
+
Then an InvalidExternalInput exception is raised
|
|
@@ -1,57 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
### Install
|
|
2
2
|
|
|
3
|
-
[
|
|
3
|
+
As a prerequisite, get [libsodium] version (>= 0.4.3) on you machine. This is the underlying cryptographic library that Vault Tree depends on.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[libsodium]: https://github.com/jedisct1/libsodium
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
* If you are on _OSX_ there is a [brew] package available. So just:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
```
|
|
10
|
+
brew install libsodium
|
|
11
|
+
```
|
|
11
12
|
|
|
12
|
-
[
|
|
13
|
+
[brew]: http://brew.sh/
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
* If you're on a Debian based system, there is no _apt-get_ package that I know of, but there
|
|
16
|
+
are some helpful install scripts on the web.
|
|
17
|
+
|
|
18
|
+
Now that you have libsodium, if you're a Ruby developer you know the drill from here:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
gem install vault-tree
|
|
17
22
|
```
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
and then
|
|
20
25
|
|
|
21
|
-
```
|
|
22
|
-
|
|
26
|
+
```ruby
|
|
27
|
+
require 'vault-tree'
|
|
23
28
|
```
|
|
29
|
+
somewhere before you use it.
|
|
30
|
+
|
|
31
|
+
### Usage
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
Executing contracts in your Ruby application is is simple.
|
|
26
34
|
|
|
27
|
-
|
|
35
|
+
Instantiate a new contract object with its corresponding JSON:
|
|
28
36
|
|
|
29
|
-
```
|
|
30
|
-
|
|
37
|
+
```ruby
|
|
38
|
+
@contract = VaultTree::Contract.new(contract_json)
|
|
31
39
|
```
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
From here you have two methods available:
|
|
34
42
|
|
|
43
|
+
```ruby
|
|
44
|
+
@contract.close_vault('vault_id', external_input = {})
|
|
35
45
|
```
|
|
36
|
-
/vagrant
|
|
37
|
-
```
|
|
38
|
-
and run
|
|
39
46
|
|
|
47
|
+
```ruby
|
|
48
|
+
@contract.open_vault('vault_id', external_input = {})
|
|
40
49
|
```
|
|
41
|
-
bundle
|
|
42
|
-
rake
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
This will pull down the latest version of the code from [Ruby Gems] and then run all the core contracts and put you in a good spot to start exploring the library.
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
### Testing
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
[main repo]: https://github.com/VaultTree/vault-tree
|
|
51
|
-
[Ruby Gems]: http://rubygems.org
|
|
53
|
+
A great way to get going is to simply run the tests:
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
* clone the repo
|
|
56
|
+
* bundle your dependencies
|
|
57
|
+
* run `rake`
|
|
54
58
|
|
|
55
|
-
|
|
59
|
+
You should see a full suite of green tests that will give you plenty of living
|
|
60
|
+
examples of to use Vault Tree in your own application.
|
|
56
61
|
|
|
57
|
-
[
|
|
62
|
+
[Documentation]: https://www.relishapp.com/vault-tree/vault-tree/docs
|
|
@@ -7,51 +7,51 @@ Scenario: Lock with Generated Key. Unlock with Assembled Shamir Key
|
|
|
7
7
|
"header": {},
|
|
8
8
|
"vaults": {
|
|
9
9
|
"s_1":{
|
|
10
|
-
"fill_with": "
|
|
10
|
+
"fill_with": "SHAMIR_SHARE['share_collection','1']",
|
|
11
11
|
"lock_with": "UNLOCKED",
|
|
12
12
|
"unlock_with": "UNLOCKED",
|
|
13
13
|
"contents": ""
|
|
14
14
|
},
|
|
15
|
-
|
|
16
15
|
"s_2":{
|
|
17
|
-
"fill_with": "
|
|
16
|
+
"fill_with": "SHAMIR_SHARE['share_collection','2']",
|
|
18
17
|
"lock_with": "UNLOCKED",
|
|
19
18
|
"unlock_with": "UNLOCKED",
|
|
20
19
|
"contents": ""
|
|
21
20
|
},
|
|
22
|
-
|
|
23
21
|
"s_3":{
|
|
24
|
-
"fill_with": "
|
|
22
|
+
"fill_with": "SHAMIR_SHARE['share_collection','3']",
|
|
25
23
|
"lock_with": "UNLOCKED",
|
|
26
24
|
"unlock_with": "UNLOCKED",
|
|
27
25
|
"contents": ""
|
|
28
26
|
},
|
|
29
|
-
|
|
30
27
|
"s_4":{
|
|
31
|
-
"fill_with": "
|
|
28
|
+
"fill_with": "SHAMIR_SHARE['share_collection','4']",
|
|
32
29
|
"lock_with": "UNLOCKED",
|
|
33
30
|
"unlock_with": "UNLOCKED",
|
|
34
31
|
"contents": ""
|
|
35
32
|
},
|
|
36
|
-
|
|
37
33
|
"s_5":{
|
|
38
|
-
"fill_with": "
|
|
34
|
+
"fill_with": "SHAMIR_SHARE['share_collection','5']",
|
|
35
|
+
"lock_with": "UNLOCKED",
|
|
36
|
+
"unlock_with": "UNLOCKED",
|
|
37
|
+
"contents": ""
|
|
38
|
+
},
|
|
39
|
+
"share_collection":{
|
|
40
|
+
"fill_with": "SHAMIR_KEY_SHARES['5','3']",
|
|
39
41
|
"lock_with": "UNLOCKED",
|
|
40
42
|
"unlock_with": "UNLOCKED",
|
|
41
43
|
"contents": ""
|
|
42
44
|
},
|
|
43
|
-
|
|
44
45
|
"message":{
|
|
45
|
-
"fill_with": "
|
|
46
|
-
"lock_with": "
|
|
46
|
+
"fill_with": "EXTERNAL_INPUT['msg']",
|
|
47
|
+
"lock_with": "ASSEMBLED_SHAMIR_KEY['s_1','s_2','s_3','s_4','s_5']",
|
|
47
48
|
"unlock_with": "ASSEMBLED_SHAMIR_KEY['s_1','s_2','s_3','s_4','s_5']",
|
|
48
49
|
"contents": ""
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
"""
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Then
|
|
56
|
-
|
|
57
|
-
Then I successfully gather the locked shares and unlock the message
|
|
54
|
+
When I lock away the shamir key share collection
|
|
55
|
+
And I close the key shares in their respective vaults
|
|
56
|
+
Then I can lock away a message with the key assembled from the shares
|
|
57
|
+
And if all the shares are available I can unlock the message
|
|
@@ -18,15 +18,15 @@ Scenario: Asymmetric Vault
|
|
|
18
18
|
"header": {},
|
|
19
19
|
"vaults": {
|
|
20
20
|
"asymmetric_message":{
|
|
21
|
-
"fill_with": "
|
|
21
|
+
"fill_with": "EXTERNAL_INPUT['asymmetric_message']",
|
|
22
22
|
"lock_with": "DH_KEY['another_public_key','my_decryption_key']",
|
|
23
23
|
"unlock_with": "DH_KEY['my_public_key','another_decryption_key']",
|
|
24
24
|
"contents": ""
|
|
25
25
|
},
|
|
26
26
|
"my_decryption_key":{
|
|
27
27
|
"fill_with": "DECRYPTION_KEY",
|
|
28
|
-
"lock_with": "
|
|
29
|
-
"unlock_with": "
|
|
28
|
+
"lock_with": "UNLOCKED",
|
|
29
|
+
"unlock_with": "UNLOCKED",
|
|
30
30
|
"contents": ""
|
|
31
31
|
},
|
|
32
32
|
"my_public_key":{
|
|
@@ -37,8 +37,8 @@ Scenario: Asymmetric Vault
|
|
|
37
37
|
},
|
|
38
38
|
"another_decryption_key":{
|
|
39
39
|
"fill_with": "DECRYPTION_KEY",
|
|
40
|
-
"lock_with": "
|
|
41
|
-
"unlock_with": "
|
|
40
|
+
"lock_with": "UNLOCKED",
|
|
41
|
+
"unlock_with": "UNLOCKED",
|
|
42
42
|
"contents": ""
|
|
43
43
|
},
|
|
44
44
|
"another_public_key":{
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Feature: External Inputs
|
|
2
|
+
|
|
3
|
+
The Vault Tree interpreter does not interact directly with outside networks. Its
|
|
4
|
+
repsonsibility is limited to opening and closing vaults under the assumption
|
|
5
|
+
that all necessary external inputs will be explicitly passed in.
|
|
6
|
+
|
|
7
|
+
Use the EXTERNAL_INPUT Keyword when you want to fill a vault with a string from
|
|
8
|
+
the outside environment.
|
|
9
|
+
|
|
10
|
+
Although you can lock and unlock vaults directly with an EXTERNAL_INPUT string
|
|
11
|
+
if it happens to be properly formated, it is recommended that you do not do this.
|
|
12
|
+
|
|
13
|
+
Instead, lock and unlock vaults with external strings using the EXTERNAL_KEY phrase.
|
|
14
|
+
EXTERNAL_KEY ensures your password is run through a secure hash before it is used to
|
|
15
|
+
lock contents. Hashing guarentees a properly padded vault key and keeps the locked vault
|
|
16
|
+
more secure if you have a weak password.
|
|
17
|
+
|
|
18
|
+
Scenario: Close And Open Using with a Key
|
|
19
|
+
Given the blank contract:
|
|
20
|
+
"""javascript
|
|
21
|
+
{
|
|
22
|
+
"header": {},
|
|
23
|
+
"vaults": {
|
|
24
|
+
"message":{
|
|
25
|
+
"description": "Simple Congratulations Message",
|
|
26
|
+
"fill_with": "EXTERNAL_INPUT['msg']",
|
|
27
|
+
"lock_with": "EXTERNAL_INPUT['secret']",
|
|
28
|
+
"unlock_with": "EXTERNAL_INPUT['secret']",
|
|
29
|
+
"contents": ""
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
"""
|
|
34
|
+
When I lock the external input in a vault using a symmetric vault key
|
|
35
|
+
Then I can recover the input message using the same key
|