trustworthy 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +51 -19
- data/bin/trustworthy +2 -140
- data/lib/trustworthy/cli/add_key.rb +22 -0
- data/lib/trustworthy/cli/command.rb +63 -0
- data/lib/trustworthy/cli/decrypt.rb +52 -0
- data/lib/trustworthy/cli/encrypt.rb +52 -0
- data/lib/trustworthy/cli/helpers.rb +64 -0
- data/lib/trustworthy/cli/init.rb +50 -0
- data/lib/trustworthy/cli.rb +47 -0
- data/lib/trustworthy/master_key.rb +14 -13
- data/lib/trustworthy/settings.rb +30 -37
- data/lib/trustworthy/version.rb +1 -1
- data/lib/trustworthy.rb +7 -4
- data/spec/spec_helper.rb +19 -7
- data/spec/trustworthy/cli/add_key_spec.rb +37 -0
- data/spec/trustworthy/cli/command_spec.rb +114 -0
- data/spec/trustworthy/cli/decrypt_spec.rb +63 -0
- data/spec/trustworthy/cli/encrypt_spec.rb +64 -0
- data/spec/trustworthy/cli/init_spec.rb +111 -0
- data/spec/trustworthy/master_key_spec.rb +12 -12
- data/spec/trustworthy/settings_spec.rb +54 -59
- metadata +51 -52
- data/lib/trustworthy/crypto.rb +0 -50
- data/spec/trustworthy/crypto_spec.rb +0 -42
data/lib/trustworthy/settings.rb
CHANGED
@@ -1,63 +1,56 @@
|
|
1
1
|
module Trustworthy
|
2
2
|
class Settings
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
new(yaml['keys'], yaml['secrets'])
|
3
|
+
def self.open(filename)
|
4
|
+
store = YAML::Store.new(filename)
|
5
|
+
store.transaction do
|
6
|
+
yield Trustworthy::Settings.new(store)
|
7
|
+
end
|
9
8
|
end
|
10
9
|
|
11
|
-
def initialize(
|
12
|
-
@
|
13
|
-
@secrets = secrets
|
10
|
+
def initialize(store)
|
11
|
+
@store = store
|
14
12
|
end
|
15
13
|
|
16
14
|
def add_key(key, username, password)
|
17
15
|
salt = SCrypt::Engine.generate_salt
|
18
16
|
|
19
|
-
|
17
|
+
cipher = _cipher_from_password(salt, password)
|
18
|
+
nonce = Trustworthy::Cipher.generate_nonce
|
20
19
|
plaintext = "#{key.x.to_s('F')},#{key.y.to_s('F')}"
|
21
|
-
ciphertext =
|
20
|
+
ciphertext = cipher.encrypt(nonce, '', plaintext)
|
22
21
|
|
23
|
-
@
|
22
|
+
@store[username] = {
|
24
23
|
'salt' => salt,
|
25
|
-
'
|
26
|
-
'authentication' => crypto.sign(ciphertext)
|
24
|
+
'encrypted_point' => nonce + ciphertext,
|
27
25
|
}
|
28
26
|
end
|
29
27
|
|
30
|
-
def
|
31
|
-
@
|
28
|
+
def empty?
|
29
|
+
@store.roots.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_key(username)
|
33
|
+
@store[username]
|
32
34
|
end
|
33
35
|
|
34
36
|
def unlock_key(username, password)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
key = find_key(username)
|
38
|
+
salt = key['salt']
|
39
|
+
ciphertext = key['encrypted_point']
|
40
|
+
ciphertext.force_encoding('BINARY') if ciphertext.respond_to?(:force_encoding)
|
41
|
+
nonce = ciphertext.slice(0, Trustworthy::Cipher.nonce_len)
|
42
|
+
ciphertext = ciphertext.slice(Trustworthy::Cipher.nonce_len..-1)
|
43
|
+
|
44
|
+
cipher = _cipher_from_password(salt, password)
|
45
|
+
plaintext = cipher.decrypt(nonce, '', ciphertext)
|
42
46
|
x, y = plaintext.split(',').map { |n| BigDecimal.new(n) }
|
43
47
|
Trustworthy::Key.new(x, y)
|
44
48
|
end
|
45
49
|
|
46
|
-
def
|
47
|
-
File.open(filename, 'w') do |file|
|
48
|
-
data = YAML.dump('keys' => @keys, 'secrets' => @secrets)
|
49
|
-
file.write(data)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def _crypto_from_password(salt, password)
|
50
|
+
def _cipher_from_password(salt, password)
|
54
51
|
cost, salt = salt.rpartition('$')
|
55
|
-
|
56
|
-
|
57
|
-
encryption_key = raw_key.slice(0, 32)
|
58
|
-
authentication_key = raw_key.slice(32, 32)
|
59
|
-
|
60
|
-
Trustworthy::Crypto.new(encryption_key, authentication_key)
|
52
|
+
key = SCrypt::Engine.scrypt(password, salt, cost, 64)
|
53
|
+
Trustworthy::Cipher.new(key)
|
61
54
|
end
|
62
55
|
end
|
63
56
|
end
|
data/lib/trustworthy/version.rb
CHANGED
data/lib/trustworthy.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
|
+
require 'aead'
|
1
2
|
require 'bigdecimal'
|
2
3
|
require 'hkdf'
|
3
|
-
require 'openssl'
|
4
|
-
require 'posix/spawn'
|
5
4
|
require 'scrypt'
|
6
5
|
require 'securerandom'
|
7
|
-
require 'trustworthy/crypto'
|
8
6
|
require 'trustworthy/key'
|
9
7
|
require 'trustworthy/master_key'
|
10
8
|
require 'trustworthy/random'
|
11
9
|
require 'trustworthy/settings'
|
12
10
|
require 'trustworthy/version'
|
13
|
-
require 'yaml'
|
11
|
+
require 'yaml/store'
|
12
|
+
|
13
|
+
module Trustworthy
|
14
|
+
CipherAlgorithm = 'AES-256-CBC-HMAC-SHA-256'
|
15
|
+
Cipher = AEAD::Cipher.new(CipherAlgorithm)
|
16
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,30 @@
|
|
1
|
-
require 'fakefs/safe'
|
2
|
-
|
3
1
|
require 'trustworthy'
|
2
|
+
require 'trustworthy/cli'
|
3
|
+
require 'construct'
|
4
|
+
require 'highline/simulate'
|
4
5
|
|
5
6
|
RSpec.configure do |config|
|
6
7
|
config.order = 'random'
|
8
|
+
config.include Construct::Helpers
|
7
9
|
config.before(:each) do
|
8
10
|
Trustworthy::Random.stub(:_source).and_return('/dev/urandom')
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
12
|
-
module
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
module TestValues
|
15
|
+
SettingsFile = 'trustworthy.yml'
|
16
|
+
InitializationVector = ['39164ec082fb8b7336d3c5500af99dcb'].pack('H*')
|
17
|
+
Plaintext = 'the chair is against the wall'
|
18
|
+
Ciphertext = ['39164ec082fb8b7336d3c5500af99dcb6f5eac5d817a65b8ac7c5ed80691db36904e1ce613a1057d807b37127d927a4b0a9a1b951ef576fc9a9edca0ef5b83e2bae850a8b3b79bfeddff892d1941d439'].pack('H*')
|
19
|
+
Salt = '400$8$1b$3e31f076a3226825'
|
20
|
+
MasterKey = Trustworthy::MasterKey.new(BigDecimal.new('1'), BigDecimal.new('5'))
|
21
|
+
EncryptedPoint = ['39164ec082fb8b7336d3c5500af99dcb17d2e60496ed553dfab4b05c568aa9260cb8e53930911c8e718bc97eb88def400e5cac1e4ee3d15060920c25d1346285'].pack('H*')
|
22
|
+
EncryptedFile = ['39164ec082fb8b7336d3c5500af99dcba37f59607382f87a2da14881a9e1eabd23965d46d7c1a651b0c930cd0ee756d9358d67edaaba02a22e902136a2a90953672c2937b0cbaac0167922918578a98c'].pack('H*')
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_config(filename)
|
26
|
+
Trustworthy::Settings.open(filename) do |settings|
|
27
|
+
settings.add_key(TestValues::MasterKey.create_key, 'user1', 'password1')
|
28
|
+
settings.add_key(TestValues::MasterKey.create_key, 'user2', 'password2')
|
17
29
|
end
|
18
30
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Trustworthy::CLI::AddKey do
|
4
|
+
before(:each) do
|
5
|
+
$terminal.stub(:say)
|
6
|
+
end
|
7
|
+
|
8
|
+
around(:each) do |example|
|
9
|
+
within_construct do |construct|
|
10
|
+
construct.file(TestValues::SettingsFile)
|
11
|
+
create_config(TestValues::SettingsFile)
|
12
|
+
example.run
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'run' do
|
17
|
+
it 'should add a new user' do
|
18
|
+
HighLine::Simulate.with(
|
19
|
+
'user1',
|
20
|
+
'password1',
|
21
|
+
'user2',
|
22
|
+
'password2',
|
23
|
+
'user3',
|
24
|
+
'password3',
|
25
|
+
'password3'
|
26
|
+
) do
|
27
|
+
Trustworthy::CLI::AddKey.new.run([])
|
28
|
+
end
|
29
|
+
|
30
|
+
contents = File.read(TestValues::SettingsFile)
|
31
|
+
subkeys = YAML.load(contents)
|
32
|
+
subkeys.should have_key('user1')
|
33
|
+
subkeys.should have_key('user2')
|
34
|
+
subkeys.should have_key('user3')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Trustworthy::CLI::Command do
|
4
|
+
def test_command
|
5
|
+
return @klass if @klass
|
6
|
+
@klass = Class.new
|
7
|
+
@klass.send(:include, Trustworthy::CLI::Command)
|
8
|
+
@klass
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
$terminal.stub(:say)
|
13
|
+
end
|
14
|
+
|
15
|
+
around(:each) do |example|
|
16
|
+
within_construct do |construct|
|
17
|
+
construct.file(TestValues::SettingsFile)
|
18
|
+
create_config(TestValues::SettingsFile)
|
19
|
+
example.run
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'unlock_master_key' do
|
24
|
+
it 'should require two distinct keys to unlock' do
|
25
|
+
command = test_command.new
|
26
|
+
command.should_receive(:error).with('Key user1 is already in use')
|
27
|
+
|
28
|
+
HighLine::Simulate.with(
|
29
|
+
'user1',
|
30
|
+
'password1',
|
31
|
+
'user1',
|
32
|
+
'user2',
|
33
|
+
'password2'
|
34
|
+
) do
|
35
|
+
Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
|
36
|
+
master_key = command.unlock_master_key(settings)
|
37
|
+
master_key.should == TestValues::MasterKey
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should required an existing user for the first key' do
|
43
|
+
command = test_command.new
|
44
|
+
command.should_receive(:error).with('Key missing does not exist')
|
45
|
+
|
46
|
+
HighLine::Simulate.with(
|
47
|
+
'missing',
|
48
|
+
'user1',
|
49
|
+
'password1',
|
50
|
+
'user2',
|
51
|
+
'password2'
|
52
|
+
) do
|
53
|
+
Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
|
54
|
+
master_key = command.unlock_master_key(settings)
|
55
|
+
master_key.should == TestValues::MasterKey
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should required an existing user for the second key' do
|
61
|
+
command = test_command.new
|
62
|
+
command.should_receive(:error).with('Key missing does not exist')
|
63
|
+
|
64
|
+
HighLine::Simulate.with(
|
65
|
+
'user1',
|
66
|
+
'password1',
|
67
|
+
'missing',
|
68
|
+
'user2',
|
69
|
+
'password2'
|
70
|
+
) do
|
71
|
+
Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
|
72
|
+
master_key = command.unlock_master_key(settings)
|
73
|
+
master_key.should == TestValues::MasterKey
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should prompt for the correct password for the first key' do
|
79
|
+
command = test_command.new
|
80
|
+
command.should_receive(:error).with('Password incorrect for user1')
|
81
|
+
|
82
|
+
HighLine::Simulate.with(
|
83
|
+
'user1',
|
84
|
+
'bad_password',
|
85
|
+
'password1',
|
86
|
+
'user2',
|
87
|
+
'password2'
|
88
|
+
) do
|
89
|
+
Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
|
90
|
+
master_key = command.unlock_master_key(settings)
|
91
|
+
master_key.should == TestValues::MasterKey
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should prompt for the correct password for the second key' do
|
97
|
+
command = test_command.new
|
98
|
+
command.should_receive(:error).with('Password incorrect for user2')
|
99
|
+
|
100
|
+
HighLine::Simulate.with(
|
101
|
+
'user1',
|
102
|
+
'password1',
|
103
|
+
'user2',
|
104
|
+
'bad_password',
|
105
|
+
'password2'
|
106
|
+
) do
|
107
|
+
Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
|
108
|
+
master_key = command.unlock_master_key(settings)
|
109
|
+
master_key.should == TestValues::MasterKey
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Trustworthy::CLI::Decrypt do
|
4
|
+
before(:each) do
|
5
|
+
$terminal.stub(:say)
|
6
|
+
end
|
7
|
+
|
8
|
+
around(:each) do |example|
|
9
|
+
within_construct do |construct|
|
10
|
+
construct.file(TestValues::SettingsFile)
|
11
|
+
construct.file('input.txt', TestValues::EncryptedFile)
|
12
|
+
construct.file('output.txt')
|
13
|
+
create_config(TestValues::SettingsFile)
|
14
|
+
example.run
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'run' do
|
19
|
+
it 'should unlock the master key and decrypt the file' do
|
20
|
+
HighLine::Simulate.with(
|
21
|
+
'user1',
|
22
|
+
'password1',
|
23
|
+
'user2',
|
24
|
+
'password2'
|
25
|
+
) do
|
26
|
+
Trustworthy::CLI::Decrypt.new.run(['-i', 'input.txt', '-o', 'output.txt'])
|
27
|
+
end
|
28
|
+
|
29
|
+
File.open('output.txt', 'rb') do |file|
|
30
|
+
ciphertext = file.read
|
31
|
+
ciphertext.should == TestValues::Plaintext
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should require an input file' do
|
36
|
+
HighLine::Simulate.with(
|
37
|
+
'user1',
|
38
|
+
'password1',
|
39
|
+
'user2',
|
40
|
+
'password2'
|
41
|
+
) do
|
42
|
+
decrypt = Trustworthy::CLI::Encrypt.new
|
43
|
+
decrypt.should_receive(:error).with('Must provide an input file')
|
44
|
+
decrypt.should_receive(:print_help)
|
45
|
+
decrypt.run([])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should require an output file' do
|
50
|
+
HighLine::Simulate.with(
|
51
|
+
'user1',
|
52
|
+
'password1',
|
53
|
+
'user2',
|
54
|
+
'password2'
|
55
|
+
) do
|
56
|
+
decrypt = Trustworthy::CLI::Encrypt.new
|
57
|
+
decrypt.should_receive(:error).with('Must provide an output file')
|
58
|
+
decrypt.should_receive(:print_help)
|
59
|
+
decrypt.run(['-i', 'input.txt'])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Trustworthy::CLI::Encrypt do
|
4
|
+
before(:each) do
|
5
|
+
$terminal.stub(:say)
|
6
|
+
AEAD::Cipher::AES_256_CBC_HMAC_SHA_256.stub(:generate_nonce).and_return(TestValues::InitializationVector)
|
7
|
+
end
|
8
|
+
|
9
|
+
around(:each) do |example|
|
10
|
+
within_construct do |construct|
|
11
|
+
construct.file(TestValues::SettingsFile)
|
12
|
+
construct.file('input.txt', TestValues::Plaintext)
|
13
|
+
construct.file('output.txt')
|
14
|
+
create_config(TestValues::SettingsFile)
|
15
|
+
example.run
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'run' do
|
20
|
+
it 'should unlock the master key and encrypt the file' do
|
21
|
+
HighLine::Simulate.with(
|
22
|
+
'user1',
|
23
|
+
'password1',
|
24
|
+
'user2',
|
25
|
+
'password2'
|
26
|
+
) do
|
27
|
+
Trustworthy::CLI::Encrypt.new.run(['-i', 'input.txt', '-o', 'output.txt'])
|
28
|
+
end
|
29
|
+
|
30
|
+
File.open('output.txt', 'rb') do |file|
|
31
|
+
ciphertext = file.read
|
32
|
+
ciphertext.should == TestValues::EncryptedFile
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should require an input file' do
|
37
|
+
HighLine::Simulate.with(
|
38
|
+
'user1',
|
39
|
+
'password1',
|
40
|
+
'user2',
|
41
|
+
'password2'
|
42
|
+
) do
|
43
|
+
encrypt = Trustworthy::CLI::Encrypt.new
|
44
|
+
encrypt.should_receive(:error).with('Must provide an input file')
|
45
|
+
encrypt.should_receive(:print_help)
|
46
|
+
encrypt.run([])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should require an output file' do
|
51
|
+
HighLine::Simulate.with(
|
52
|
+
'user1',
|
53
|
+
'password1',
|
54
|
+
'user2',
|
55
|
+
'password2'
|
56
|
+
) do
|
57
|
+
encrypt = Trustworthy::CLI::Encrypt.new
|
58
|
+
encrypt.should_receive(:error).with('Must provide an output file')
|
59
|
+
encrypt.should_receive(:print_help)
|
60
|
+
encrypt.run(['-i', 'input.txt'])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Trustworthy::CLI::Init do
|
4
|
+
before(:each) do
|
5
|
+
$terminal.stub(:say)
|
6
|
+
end
|
7
|
+
|
8
|
+
around(:each) do |example|
|
9
|
+
within_construct do |construct|
|
10
|
+
construct.file(TestValues::SettingsFile)
|
11
|
+
example.run
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'run' do
|
16
|
+
it 'should not allow any previous keys to exist' do
|
17
|
+
create_config(TestValues::SettingsFile)
|
18
|
+
$terminal.should_receive(:say).with(/Config trustworthy\.yml already exists/)
|
19
|
+
Trustworthy::CLI::Init.new.run([])
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should write a settings file' do
|
23
|
+
HighLine::Simulate.with(
|
24
|
+
'user1',
|
25
|
+
'password1',
|
26
|
+
'password1',
|
27
|
+
'user2',
|
28
|
+
'password2',
|
29
|
+
'password2'
|
30
|
+
) do
|
31
|
+
Trustworthy::CLI::Init.new.run([])
|
32
|
+
end
|
33
|
+
|
34
|
+
contents = File.read(TestValues::SettingsFile)
|
35
|
+
subkeys = YAML.load(contents)
|
36
|
+
subkeys.should have_key('user1')
|
37
|
+
subkeys.should have_key('user2')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should confirm passwords' do
|
41
|
+
HighLine::Simulate.with(
|
42
|
+
'user1',
|
43
|
+
'password1',
|
44
|
+
'password2',
|
45
|
+
'password1',
|
46
|
+
'password1',
|
47
|
+
'user2',
|
48
|
+
'password2',
|
49
|
+
'password2'
|
50
|
+
) do
|
51
|
+
Trustworthy::CLI::Init.new.run([])
|
52
|
+
end
|
53
|
+
|
54
|
+
contents = File.read(TestValues::SettingsFile)
|
55
|
+
subkeys = YAML.load(contents)
|
56
|
+
subkeys.should have_key('user1')
|
57
|
+
subkeys.should have_key('user2')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should write to a specified file' do
|
61
|
+
filename = 'test.yml'
|
62
|
+
within_construct do |construct|
|
63
|
+
construct.file(filename)
|
64
|
+
HighLine::Simulate.with(
|
65
|
+
'user1',
|
66
|
+
'password1',
|
67
|
+
'password1',
|
68
|
+
'user2',
|
69
|
+
'password2',
|
70
|
+
'password2'
|
71
|
+
) do
|
72
|
+
Trustworthy::CLI::Init.new.run(['-c', filename])
|
73
|
+
end
|
74
|
+
|
75
|
+
contents = File.read(filename)
|
76
|
+
subkeys = YAML.load(contents)
|
77
|
+
subkeys.should have_key('user1')
|
78
|
+
subkeys.should have_key('user2')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should generate the specified number of keys' do
|
83
|
+
HighLine::Simulate.with(
|
84
|
+
'user1',
|
85
|
+
'password1',
|
86
|
+
'password1',
|
87
|
+
'user2',
|
88
|
+
'password2',
|
89
|
+
'password2',
|
90
|
+
'user3',
|
91
|
+
'password3',
|
92
|
+
'password3'
|
93
|
+
) do
|
94
|
+
Trustworthy::CLI::Init.new.run(['-k', '3'])
|
95
|
+
end
|
96
|
+
|
97
|
+
contents = File.read(TestValues::SettingsFile)
|
98
|
+
subkeys = YAML.load(contents)
|
99
|
+
subkeys.should have_key('user1')
|
100
|
+
subkeys.should have_key('user2')
|
101
|
+
subkeys.should have_key('user3')
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should require two subkeys minimum' do
|
105
|
+
init = Trustworthy::CLI::Init.new
|
106
|
+
init.should_receive(:error).with('Must generate at least two keys')
|
107
|
+
init.should_receive(:print_help)
|
108
|
+
init.run(['-k', '1'])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -6,11 +6,11 @@ describe Trustworthy::MasterKey do
|
|
6
6
|
key1 = master_key.create_key
|
7
7
|
key2 = master_key.create_key
|
8
8
|
|
9
|
-
ciphertext = master_key.encrypt(
|
9
|
+
ciphertext = master_key.encrypt(TestValues::Plaintext)
|
10
10
|
|
11
11
|
new_master_key = Trustworthy::MasterKey.create_from_keys(key1, key2)
|
12
12
|
plaintext = new_master_key.decrypt(ciphertext)
|
13
|
-
plaintext.should ==
|
13
|
+
plaintext.should == TestValues::Plaintext
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should function with any 2 of n keys' do
|
@@ -18,14 +18,14 @@ describe Trustworthy::MasterKey do
|
|
18
18
|
key1 = master_key1.create_key
|
19
19
|
key2 = master_key1.create_key
|
20
20
|
|
21
|
-
ciphertext = master_key1.encrypt(
|
21
|
+
ciphertext = master_key1.encrypt(TestValues::Plaintext)
|
22
22
|
|
23
23
|
master_key2 = Trustworthy::MasterKey.create_from_keys(key1, key2)
|
24
24
|
key3 = master_key2.create_key
|
25
25
|
|
26
26
|
master_key3 = Trustworthy::MasterKey.create_from_keys(key1, key3)
|
27
27
|
plaintext = master_key3.decrypt(ciphertext)
|
28
|
-
plaintext.should ==
|
28
|
+
plaintext.should == TestValues::Plaintext
|
29
29
|
end
|
30
30
|
|
31
31
|
describe 'self.create' do
|
@@ -63,25 +63,25 @@ describe Trustworthy::MasterKey do
|
|
63
63
|
|
64
64
|
describe 'encrypt' do
|
65
65
|
it 'should encrypt and sign the data using the intercept' do
|
66
|
-
|
66
|
+
AEAD::Cipher::AES_256_CBC_HMAC_SHA_256.stub(:generate_nonce).and_return(TestValues::InitializationVector)
|
67
67
|
master_key = Trustworthy::MasterKey.new(BigDecimal.new('6'), BigDecimal.new('24'))
|
68
|
-
ciphertext = master_key.encrypt(
|
69
|
-
ciphertext.should ==
|
68
|
+
ciphertext = master_key.encrypt(TestValues::Plaintext)
|
69
|
+
ciphertext.should == TestValues::Ciphertext
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
73
|
describe 'decrypt' do
|
74
74
|
it 'should decrypt and verify the data using the intercept' do
|
75
75
|
master_key = Trustworthy::MasterKey.new(BigDecimal.new('6'), BigDecimal.new('24'))
|
76
|
-
|
77
|
-
plaintext
|
78
|
-
plaintext.should == 'foobar'
|
76
|
+
plaintext = master_key.decrypt(TestValues::Ciphertext)
|
77
|
+
plaintext.should == TestValues::Plaintext
|
79
78
|
end
|
80
79
|
|
81
80
|
it 'should raise an invalid signature error if signatures do not match' do
|
82
81
|
master_key = Trustworthy::MasterKey.new(BigDecimal.new('6'), BigDecimal.new('24'))
|
83
|
-
ciphertext =
|
84
|
-
expect { master_key.decrypt(ciphertext) }.to raise_error('
|
82
|
+
ciphertext = TestValues::Ciphertext.next
|
83
|
+
expect { master_key.decrypt(ciphertext) }.to raise_error(ArgumentError, 'ciphertext failed authentication step')
|
85
84
|
end
|
86
85
|
end
|
87
86
|
end
|
87
|
+
|