trustworthy 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0bb4a8a2dc975dae29a9fdc798baa2f38fc3368b
4
- data.tar.gz: 87d2308517917931f4b5ebfe6e51d9b992d3e387
3
+ metadata.gz: 5fef54ec026c8c04c1e46553eb5c7250a88dac46
4
+ data.tar.gz: 29a151ecda817fdaaa0bbee90d0e60c8315d8957
5
5
  SHA512:
6
- metadata.gz: 99ccfc9b7e5df3ac5277a0e9a75b92963b8c5a98f9264eb5693a63bd0ec69ec7772099382b5d446aa2cc7a4476ff7e2d50fe1070ef598535fa2dd394e60ea6b3
7
- data.tar.gz: e0afdedd53d39762b7c2c577224831e50315b1ffaff7e8971169fc9ce71bd1d0875a7b696e562be0588f1829c474a63d7654d8ec3d8694b8693f2663b4c8c0cb
6
+ metadata.gz: 0a9ee151b5b02ce3e0fa9be24fc9fa9d55a6315fad8b06f60aeea00d0a38626a9bdc100179a1220f0c32b7c4b67e42a299cbe43daaa48c283363062662d7661f
7
+ data.tar.gz: 487e84bea07c419cd6d7cac975d1e82bdb4800a0a5a50d15ffc92c7373761f00acf2917e034b62358538878b81882c36cc1fd1f04dd7ed2080416716999115fa
data/README.md CHANGED
@@ -36,32 +36,14 @@ The configuration uses ruby's `YAML::Store` to provide a simple transactional da
36
36
 
37
37
  ---
38
38
  a-user:
39
- salt: 400$8$28$4c7fc59a31a9f38a
40
- encrypted_point: !binary |-
41
- CWcT++kRSAw/0IAVRX6KKAfwbyWBX7ZUh4dZNxL8An413CvRL2tUhWlwsKVl
42
- ZKyzmc6VjpKqS4ZpGoPPUCu6xrIo5LkLwXVIpDsBx7SCoK72uEsxd9x0GW5i
43
- 9Mf8r40KE3gUCudntBXlxduDrqWZgW1uFFCg+U3ACt28GzGftOGjYW6PCAZO
44
- N35aHYpGHWhddWeFvbaXNrAPtLSiVWSNW35RU2qo+HS+uSYGO65r9viCXC8f
45
- 3yLZsPjtouDRyMEv5xOPVZKnvsf3Ju3EBH7Abyw/zezS2LvzrtmxHTN5yF92
46
- xphq0imIR52Yj2/k6pdRz/X/8ZsdS+HEifvvRBM+oVKQ2PQh4MIFPJuE0CWA
47
- iPnpqdvjYt0M7BsodX2K897A
39
+ salt: 400$8$23$38f426136db22836
40
+ encrypted_point: dzVzPvuzKsTJ7coFLki8tQ==--vGto+f9sQhRuPb+47rUI4oSZ7gaPGKiQtBIwB//wTcvuJOm9gyrLrjH74RKKJlkScBvYuMfnhQyn9T1bIw9obsBs4YsF8VxCsDPG26Ci82n9qOENod2pP4xVzmC4VWCnbi7Y4jS+Rgsq6xp3L2zG6Ci0GWO1bSQO8hFzaMpBiCirqMAGHf0m6Yzqu6h5NFtygcyNyxAY8YxX1oxa6Bj5UwefDKplVGTI0ZbQn9vtdwKFuwXZsv11g5+zLvvq54Z2UZ/AZu/scnhXopL5IZkiclTtX8LUi9Dob3Xpqtf6WXymudvVMG0JaxkUqqRCyWtLSFE3sNdwv+877cS8PglTIKxXIZTIh7FzdEgkLSStGnw=
48
41
  another-user:
49
- salt: 400$8$28$9dceab0f3414ab23
50
- encrypted_point: !binary |-
51
- 7B1hXxwwXDU0vTLAPj6U9+WWT3o4i1r7prPOamgStDjvv7f0gZp0D3T56gZk
52
- b+2Q4zwyhTM4p6DS0xdG3lfhnkQEYQ6tROnLbI1O7IvuOmFVsDNLej9ps7hJ
53
- e1kdFiLaF3efRYtHs2GYdEVrRWWDFgfLDVFVoFbqDruRX1ltTVuaJvS9f7Qb
54
- FPI8a2gJ0sl+1B5eBJeR1Chbdn3rHxK7SHq+J/SAJV7xKmkQa6B8g2V1D3xE
55
- oB45Gmgm9o1s1/van72ckT91HPh55B8tHnjeZZwdHEp7Z8lyLrDxhbpQm7ql
56
- ESpbM8BvdFCmzns5ZSku5Jgc78MwQ5YO1y/QXY+s9so7SDLI9yF18q4no81f
57
- sNpbmdY+NolXChlDRZcZ9qJk
42
+ salt: 400$8$23$df3b3153ee94da81
43
+ encrypted_point: Shx/GRuOYz+Ts/5f5z1yDw==--1ulNtnX6Zi3z0t12TiCItE5H5dhZZONKcgt6yq1g2prJWd1q5c9ArL10BtK/9lSPoXMsyO8rURKZ3pCM4hzW043B1ksJQtyg6O71ilnSvP+4Yty8oH0SW67cGSgfkfUc0UkfcE2Osfy/YVkP/HH47qTLNTg406uJ2uWjb6OkW8sjD+mq3hp8tehyy20tEBhqyM0UOSCpvhb+EgFfYFDeG+8Gj+r4lfcdqJJvzcy5U17tpYknQm/WbnmIkvgZRFGH/NIthJdPnK43SsdPbVcSHdkw71urJ3pBmgCmyTFcdmpiSl/t1rG09f2KT63YDF+4YUSn1fuIFZXbrLez59svHbKnQ8YHvt9pCXiQHelk8Sk=
58
44
 
59
45
  ## Reference
60
46
 
61
47
  * RSA Labs - [http://www.rsa.com/rsalabs/node.asp?id=2259](http://www.rsa.com/rsalabs/node.asp?id=2259)
62
48
  * ssss - [http://point-at-infinity.org/ssss/](http://point-at-infinity.org/ssss/)
63
49
  * Secret sharing on Wikipedia - [http://en.wikipedia.org/wiki/Secret_sharing](http://en.wikipedia.org/wiki/Secret_sharing)
64
-
65
- ## License
66
-
67
- Trustworthy is released under the [MIT license](http://www.opensource.org/licenses/MIT).
@@ -10,14 +10,14 @@ module Trustworthy
10
10
  def run(args)
11
11
  options = parse_options('add-key', args)
12
12
 
13
- $terminal.say('Adding a new key to master key')
13
+ say('Adding a new key to master key')
14
14
 
15
15
  prompt = Trustworthy::Prompt.new(options[:config_file], $terminal)
16
16
  master_key = prompt.unlock_master_key
17
17
  key = master_key.create_key
18
18
  username = prompt.add_user_key(key)
19
19
 
20
- $terminal.say("Added #{username}")
20
+ say("Added #{username}")
21
21
  end
22
22
  end
23
23
  end
@@ -32,30 +32,9 @@ module Trustworthy
32
32
  end
33
33
  end
34
34
 
35
- def ask(prompt)
36
- $terminal.ask(prompt).to_s
37
- end
38
-
39
- def ask_password(prompt)
40
- $terminal.ask(prompt) { |q| q.echo = false }.to_s
41
- end
42
-
43
- def error(message)
44
- say_color(message, :error)
45
- end
46
-
47
- def info(message)
48
- say_color(message, :info)
49
- end
50
-
51
35
  def say(message)
52
36
  $terminal.say(message)
53
37
  end
54
-
55
- def say_color(message, color)
56
- colored_message = $terminal.color(message, color)
57
- say(colored_message)
58
- end
59
38
  end
60
39
  end
61
40
  end
@@ -28,8 +28,11 @@ module Trustworthy
28
28
  end
29
29
 
30
30
  prompt = Trustworthy::Prompt.new(options[:config_file], $terminal)
31
- File.open(options[:input_file], 'rb') do |input_file|
32
- ciphertext = input_file.read
31
+ File.open(options[:input_file], 'r') do |input_file|
32
+ wrapped_ciphertext = input_file.read
33
+ ciphertext = wrapped_ciphertext.gsub(/-+(BEGIN|END) TRUSTWORTHY ENCRYPTED FILE-+/, '')
34
+ ciphertext = ciphertext.gsub(/^Version: .*$/, '')
35
+ ciphertext = ciphertext.gsub("\n", '')
33
36
 
34
37
  master_key = prompt.unlock_master_key
35
38
  plaintext = master_key.decrypt(ciphertext)
@@ -38,7 +41,7 @@ module Trustworthy
38
41
  end
39
42
  end
40
43
 
41
- info "Decrypted #{options[:input_file]} to #{options[:output_file]}"
44
+ say("Decrypted #{options[:input_file]} to #{options[:output_file]}")
42
45
  end
43
46
  end
44
47
  end
@@ -32,12 +32,21 @@ module Trustworthy
32
32
  plaintext = input_file.read
33
33
  master_key = prompt.unlock_master_key
34
34
  ciphertext = master_key.encrypt(plaintext)
35
- File.open(options[:output_file], 'wb+') do |output_file|
36
- output_file.write(ciphertext)
35
+ File.open(options[:output_file], 'w+') do |output_file|
36
+ wrapped_ciphertext = ciphertext.scan(/.{1,64}/).join("\n")
37
+ output_file.write('-----BEGIN TRUSTWORTHY ENCRYPTED FILE-----')
38
+ output_file.write("\n")
39
+ output_file.write("Version: Trustworthy/#{Trustworthy::VERSION}")
40
+ output_file.write("\n")
41
+ output_file.write("\n")
42
+ output_file.write(wrapped_ciphertext)
43
+ output_file.write("\n")
44
+ output_file.write('-----END TRUSTWORTHY ENCRYPTED FILE-----')
45
+ output_file.write("\n")
37
46
  end
38
47
  end
39
48
 
40
- $terminal.say("Encrypted #{options[:input_file]} to #{options[:output_file]}")
49
+ say("Encrypted #{options[:input_file]} to #{options[:output_file]}")
41
50
  end
42
51
  end
43
52
  end
@@ -29,12 +29,12 @@ module Trustworthy
29
29
 
30
30
  Trustworthy::Settings.open(options[:config_file]) do |settings|
31
31
  unless settings.empty?
32
- $terminal.say("Config #{options[:config_file]} already exists")
32
+ say("Config #{options[:config_file]} already exists")
33
33
  return
34
34
  end
35
35
  end
36
36
 
37
- $terminal.say("Creating a new master key with #{options[:keys]} keys")
37
+ say("Creating a new master key with #{options[:keys]} keys")
38
38
 
39
39
  master_key = Trustworthy::MasterKey.create
40
40
  prompt = Trustworthy::Prompt.new(options[:config_file], $terminal)
@@ -44,7 +44,7 @@ module Trustworthy
44
44
  $terminal.say("Key #{username} added")
45
45
  end
46
46
 
47
- $terminal.say("Created #{options[:config_file]}")
47
+ say("Created #{options[:config_file]}")
48
48
  end
49
49
  end
50
50
  end
@@ -12,6 +12,8 @@ HighLine.color_scheme = HighLine::SampleColorScheme.new
12
12
 
13
13
  module Trustworthy
14
14
  class CLI
15
+ include Trustworthy::CLI::Command
16
+
15
17
  Commands = {
16
18
  'add-key' => Trustworthy::CLI::AddKey,
17
19
  'init' => Trustworthy::CLI::Init,
@@ -34,12 +36,12 @@ module Trustworthy
34
36
  end
35
37
 
36
38
  def _print_help
37
- $terminal.say("#{Trustworthy::CLI.banner}\n\n")
38
- $terminal.say('Commands:')
39
+ say("#{Trustworthy::CLI.banner}\n\n")
40
+ say('Commands:')
39
41
  Commands.each do |name, klass|
40
- $terminal.say(' %-8s %s' % [name, klass.description])
42
+ say(' %-8s %s' % [name, klass.description])
41
43
  end
42
- $terminal.say("\nSee 'trustworthy <command> --help' for more information on a specific command")
44
+ say("\nSee 'trustworthy <command> --help' for more information on a specific command")
43
45
  end
44
46
  end
45
47
  end
@@ -3,7 +3,7 @@ module Trustworthy
3
3
  attr_reader :x, :y
4
4
 
5
5
  def self.create(slope, intercept)
6
- x = Random.number
6
+ x = Trustworthy::Random.number
7
7
  y = slope * x + intercept
8
8
  new(x, y)
9
9
  end
@@ -29,13 +29,18 @@ module Trustworthy
29
29
 
30
30
  def encrypt(plaintext)
31
31
  nonce = Trustworthy::Cipher.generate_nonce
32
- nonce + _cipher.encrypt(nonce, '', plaintext)
32
+ ciphertext = _cipher.encrypt(nonce, '', plaintext)
33
+
34
+ [nonce, ciphertext].map do |field|
35
+ Base64.encode64(field).gsub("\n", '')
36
+ end.join('--')
33
37
  end
34
38
 
35
39
  def decrypt(ciphertext)
36
- ciphertext.force_encoding('BINARY') if ciphertext.respond_to?(:force_encoding)
37
- nonce = ciphertext.slice(0, Trustworthy::Cipher.nonce_len)
38
- ciphertext = ciphertext.slice(Trustworthy::Cipher.nonce_len..-1)
40
+ nonce, ciphertext = ciphertext.split('--').map do |field|
41
+ Base64.decode64(field)
42
+ end
43
+
39
44
  _cipher.decrypt(nonce, '', ciphertext)
40
45
  end
41
46
 
@@ -2,6 +2,10 @@ module Trustworthy
2
2
  class Settings
3
3
  def self.open(filename)
4
4
  store = YAML::Store.new(filename)
5
+ if store.respond_to?(:ultra_safe=)
6
+ store.ultra_safe = true
7
+ end
8
+
5
9
  store.transaction do
6
10
  yield Trustworthy::Settings.new(store)
7
11
  end
@@ -19,9 +23,13 @@ module Trustworthy
19
23
  plaintext = "#{key.x.to_s('F')},#{key.y.to_s('F')}"
20
24
  ciphertext = cipher.encrypt(nonce, '', plaintext)
21
25
 
26
+ encrypted_point = [nonce, ciphertext].map do |field|
27
+ Base64.encode64(field).gsub("\n", '')
28
+ end.join('--')
29
+
22
30
  @store[username] = {
23
31
  'salt' => salt,
24
- 'encrypted_point' => nonce + ciphertext,
32
+ 'encrypted_point' => encrypted_point
25
33
  }
26
34
  end
27
35
 
@@ -45,9 +53,10 @@ module Trustworthy
45
53
  key = find_key(username)
46
54
  salt = key['salt']
47
55
  ciphertext = key['encrypted_point']
48
- ciphertext.force_encoding('BINARY') if ciphertext.respond_to?(:force_encoding)
49
- nonce = ciphertext.slice(0, Trustworthy::Cipher.nonce_len)
50
- ciphertext = ciphertext.slice(Trustworthy::Cipher.nonce_len..-1)
56
+
57
+ nonce, ciphertext = ciphertext.split('--').map do |field|
58
+ Base64.decode64(field)
59
+ end
51
60
 
52
61
  cipher = _cipher_from_password(salt, password)
53
62
  plaintext = cipher.decrypt(nonce, '', ciphertext)
@@ -57,7 +66,7 @@ module Trustworthy
57
66
 
58
67
  def _cipher_from_password(salt, password)
59
68
  cost, salt = salt.rpartition('$')
60
- key = SCrypt::Engine.scrypt(password, salt, cost, 64)
69
+ key = SCrypt::Engine.scrypt(password, salt, cost, Trustworthy::Cipher.key_len)
61
70
  Trustworthy::Cipher.new(key)
62
71
  end
63
72
  end
@@ -1,3 +1,3 @@
1
1
  module Trustworthy
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.1'
3
3
  end
data/lib/trustworthy.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'aead'
2
+ require 'base64'
2
3
  require 'bigdecimal'
3
4
  require 'highline'
4
5
  require 'hkdf'
data/spec/spec_helper.rb CHANGED
@@ -15,11 +15,18 @@ module TestValues
15
15
  SettingsFile = 'trustworthy.yml'
16
16
  InitializationVector = ['39164ec082fb8b7336d3c5500af99dcb'].pack('H*')
17
17
  Plaintext = 'the chair is against the wall'
18
- Ciphertext = ['39164ec082fb8b7336d3c5500af99dcb6f5eac5d817a65b8ac7c5ed80691db36904e1ce613a1057d807b37127d927a4b0a9a1b951ef576fc9a9edca0ef5b83e2bae850a8b3b79bfeddff892d1941d439'].pack('H*')
18
+ Ciphertext = 'ORZOwIL7i3M208VQCvmdyw==--b16sXYF6ZbisfF7YBpHbNpBOHOYToQV9gHs3En2SeksKmhuVHvV2/Jqe3KDvW4PiuuhQqLO3m/7d/4ktGUHUOQ=='
19
19
  Salt = '400$8$1b$3e31f076a3226825'
20
20
  MasterKey = Trustworthy::MasterKey.new(BigDecimal.new('1'), BigDecimal.new('5'))
21
- EncryptedPoint = ['39164ec082fb8b7336d3c5500af99dcb17d2e60496ed553dfab4b05c568aa9260cb8e53930911c8e718bc97eb88def400e5cac1e4ee3d15060920c25d1346285'].pack('H*')
22
- EncryptedFile = ['39164ec082fb8b7336d3c5500af99dcba37f59607382f87a2da14881a9e1eabd23965d46d7c1a651b0c930cd0ee756d9358d67edaaba02a22e902136a2a90953672c2937b0cbaac0167922918578a98c'].pack('H*')
21
+ EncryptedPoint = 'ORZOwIL7i3M208VQCvmdyw==--F9LmBJbtVT36tLBcVoqpJgy45TkwkRyOcYvJfriN70AOXKweTuPRUGCSDCXRNGKF'
22
+ EncryptedFile = <<-EOF
23
+ -----BEGIN TRUSTWORTHY ENCRYPTED FILE-----
24
+ Version: Trustworthy/#{Trustworthy::VERSION}
25
+
26
+ ORZOwIL7i3M208VQCvmdyw==--o39ZYHOC+HotoUiBqeHqvSOWXUbXwaZRsMkwzQ
27
+ 7nVtk1jWftqroCoi6QITaiqQlTZywpN7DLqsAWeSKRhXipjA==
28
+ -----END TRUSTWORTHY ENCRYPTED FILE-----
29
+ EOF
23
30
  end
24
31
 
25
32
  def create_config(filename)
@@ -26,10 +26,8 @@ describe Trustworthy::CLI::Decrypt do
26
26
  Trustworthy::CLI::Decrypt.new.run(['-i', 'input.txt', '-o', 'output.txt'])
27
27
  end
28
28
 
29
- File.open('output.txt', 'rb') do |file|
30
- ciphertext = file.read
31
- ciphertext.should == TestValues::Plaintext
32
- end
29
+ plaintext = File.read('output.txt')
30
+ plaintext.should == TestValues::Plaintext
33
31
  end
34
32
 
35
33
  it 'should require an input file' do
@@ -27,10 +27,8 @@ describe Trustworthy::CLI::Encrypt do
27
27
  Trustworthy::CLI::Encrypt.new.run(['-i', 'input.txt', '-o', 'output.txt'])
28
28
  end
29
29
 
30
- File.open('output.txt', 'rb') do |file|
31
- ciphertext = file.read
32
- ciphertext.should == TestValues::EncryptedFile
33
- end
30
+ ciphertext = File.read('output.txt')
31
+ ciphertext.should == TestValues::EncryptedFile
34
32
  end
35
33
 
36
34
  it 'should require an input file' do
@@ -79,7 +79,8 @@ describe Trustworthy::MasterKey do
79
79
 
80
80
  it 'should raise an invalid signature error if signatures do not match' do
81
81
  master_key = Trustworthy::MasterKey.new(BigDecimal.new('6'), BigDecimal.new('24'))
82
- ciphertext = TestValues::Ciphertext.next
82
+ ciphertext = TestValues::Ciphertext.dup
83
+ ciphertext[0] = ciphertext[0].next
83
84
  expect { master_key.decrypt(ciphertext) }.to raise_error(ArgumentError, 'ciphertext failed authentication step')
84
85
  end
85
86
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trustworthy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Downey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-31 00:00:00.000000000 Z
11
+ date: 2013-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aead
@@ -163,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
163
163
  version: '0'
164
164
  requirements: []
165
165
  rubyforge_project:
166
- rubygems_version: 2.0.1
166
+ rubygems_version: 2.0.3
167
167
  signing_key:
168
168
  specification_version: 4
169
169
  summary: Encrypt and decrypt files with multiple key holders