trustworthy 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5fef54ec026c8c04c1e46553eb5c7250a88dac46
4
- data.tar.gz: 29a151ecda817fdaaa0bbee90d0e60c8315d8957
3
+ metadata.gz: e42d985518ef469697ee1454988f9e2b8ff259fc
4
+ data.tar.gz: e0313923ab5df072cd1c79e4b7776348ee0876ad
5
5
  SHA512:
6
- metadata.gz: 0a9ee151b5b02ce3e0fa9be24fc9fa9d55a6315fad8b06f60aeea00d0a38626a9bdc100179a1220f0c32b7c4b67e42a299cbe43daaa48c283363062662d7661f
7
- data.tar.gz: 487e84bea07c419cd6d7cac975d1e82bdb4800a0a5a50d15ffc92c7373761f00acf2917e034b62358538878b81882c36cc1fd1f04dd7ed2080416716999115fa
6
+ metadata.gz: 1bd3eb61ba0642ef2c0ddef733b4cc2f53c04bfd027a2a6d6f1e8562b27caf778dba100495e6e80998a2257e6b4da15c08be8ff9ef057269827aa0933b33872b
7
+ data.tar.gz: a330f89c54ce12a6b8eb8500d1b5dc00f3502b1293d37500fbb2e9f659fc270fd320b3a51b1e76ddbc9c370c74eaa99074eb118e07d0ad93338067f37cd3e623
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013 John Downey
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -2,6 +2,7 @@ require 'highline/import'
2
2
  require 'optparse'
3
3
 
4
4
  require 'trustworthy/cli/command'
5
+ require 'trustworthy/cli/crypt'
5
6
  require 'trustworthy/cli/add_key'
6
7
  require 'trustworthy/cli/init'
7
8
  require 'trustworthy/cli/decrypt'
@@ -0,0 +1,50 @@
1
+ module Trustworthy
2
+ class CLI
3
+ module Crypt
4
+ def self.included(klass)
5
+ klass.extend(ClassMethods)
6
+ end
7
+
8
+ def parse_options(args)
9
+ super(_command, args) do |opts, options|
10
+ opts.on('-i', '--input FILE', "File to #{_command}") do |file|
11
+ options[:input_file] = file
12
+ end
13
+
14
+ opts.on('-o', '--output FILE', "File to write #{_command}ed contents to") do |file|
15
+ options[:output_file] = file
16
+ end
17
+ end
18
+ end
19
+
20
+ def run(args)
21
+ catch(:error) do
22
+ options = _check_options(args)
23
+ prompt = Trustworthy::Prompt.new(options[:config_file], $terminal)
24
+ File.open(options[:input_file], 'rb') do |input_file|
25
+ _transform(prompt, options, input_file)
26
+ end
27
+ end
28
+ end
29
+
30
+ def _command
31
+ self.class._command
32
+ end
33
+
34
+ def _check_options(args)
35
+ options = parse_options(args)
36
+ unless options.has_key?(:input_file) && options.has_key?(:output_file)
37
+ print_help
38
+ throw :error
39
+ end
40
+ options
41
+ end
42
+
43
+ module ClassMethods
44
+ def description
45
+ "#{_command.capitalize} a file using a master key"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -2,47 +2,35 @@ module Trustworthy
2
2
  class CLI
3
3
  class Decrypt
4
4
  include Trustworthy::CLI::Command
5
+ include Trustworthy::CLI::Crypt
5
6
 
6
- def self.description
7
- 'Decrypt a file using the master key'
7
+ def self._command
8
+ 'decrypt'
8
9
  end
9
10
 
10
- def parse_options(args)
11
- super('encrypt', args) do |opts, options|
12
- opts.on('-i', '--input FILE', 'File to decrypt') do |file|
13
- options[:input_file] = file
14
- end
15
-
16
- opts.on('-o', '--output FILE', 'File to write decrypted contents to') do |file|
17
- options[:output_file] = file
18
- end
19
- end
20
- end
21
-
22
- def run(args)
23
- options = parse_options(args)
24
-
25
- unless options.has_key?(:input_file) && options.has_key?(:output_file)
26
- print_help
27
- return
11
+ def _transform(prompt, options, input_file)
12
+ wrapped_ciphertext = input_file.read
13
+ unless wrapped_ciphertext.include?('TRUSTWORTHY ENCRYPTED FILE')
14
+ say("File #{options[:input_file]} does not appear to be a trustworthy encrypted file")
15
+ throw :error
28
16
  end
29
17
 
30
- prompt = Trustworthy::Prompt.new(options[:config_file], $terminal)
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", '')
36
-
37
- master_key = prompt.unlock_master_key
38
- plaintext = master_key.decrypt(ciphertext)
39
- File.open(options[:output_file], 'wb+') do |output_file|
40
- output_file.write(plaintext)
41
- end
18
+ master_key = prompt.unlock_master_key
19
+ ciphertext = _strip_ciphertext(wrapped_ciphertext)
20
+ plaintext = master_key.decrypt(ciphertext)
21
+ File.open(options[:output_file], 'wb+') do |output_file|
22
+ output_file.write(plaintext)
42
23
  end
43
24
 
44
25
  say("Decrypted #{options[:input_file]} to #{options[:output_file]}")
45
26
  end
27
+
28
+ def _strip_ciphertext(ciphertext)
29
+ ciphertext.
30
+ gsub(/-+(BEGIN|END) TRUSTWORTHY ENCRYPTED FILE-+/, '').
31
+ gsub(/^Version: .*$/, '').
32
+ gsub("\n", '')
33
+ end
46
34
  end
47
35
  end
48
36
  end
@@ -2,52 +2,31 @@ module Trustworthy
2
2
  class CLI
3
3
  class Encrypt
4
4
  include Trustworthy::CLI::Command
5
+ include Trustworthy::CLI::Crypt
5
6
 
6
- def self.description
7
- 'Encrypt a file using the master key'
7
+ def self._command
8
+ 'encrypt'
8
9
  end
9
10
 
10
- def parse_options(args)
11
- super('encrypt', args) do |opts, options|
12
- opts.on('-i', '--input FILE', 'File to encrypt') do |file|
13
- options[:input_file] = file
14
- end
15
-
16
- opts.on('-o', '--output FILE', 'File to write encrypted contents to') do |file|
17
- options[:output_file] = file
18
- end
19
- end
20
- end
21
-
22
- def run(args)
23
- options = parse_options(args)
24
-
25
- unless options.has_key?(:input_file) && options.has_key?(:output_file)
26
- print_help
27
- return
28
- end
29
-
30
- prompt = Trustworthy::Prompt.new(options[:config_file], $terminal)
31
- File.open(options[:input_file], 'rb') do |input_file|
32
- plaintext = input_file.read
33
- master_key = prompt.unlock_master_key
34
- ciphertext = master_key.encrypt(plaintext)
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")
46
- end
11
+ def _transform(prompt, options, input_file)
12
+ plaintext = input_file.read
13
+ master_key = prompt.unlock_master_key
14
+ ciphertext = master_key.encrypt(plaintext)
15
+ File.open(options[:output_file], 'wb+') do |output_file|
16
+ _format_ciphertext(output_file, ciphertext)
47
17
  end
48
18
 
49
19
  say("Encrypted #{options[:input_file]} to #{options[:output_file]}")
50
20
  end
21
+
22
+ def _format_ciphertext(output_file, ciphertext)
23
+ wrapped_ciphertext = ciphertext.scan(/.{1,64}/).join("\n")
24
+ output_file.puts('-----BEGIN TRUSTWORTHY ENCRYPTED FILE-----')
25
+ output_file.puts("Version: Trustworthy/#{Trustworthy::VERSION}")
26
+ output_file.puts
27
+ output_file.puts(wrapped_ciphertext)
28
+ output_file.puts('-----END TRUSTWORTHY ENCRYPTED FILE-----')
29
+ end
51
30
  end
52
31
  end
53
32
  end
@@ -8,9 +8,18 @@ module Trustworthy
8
8
  new(x, y)
9
9
  end
10
10
 
11
+ def self.create_from_string(str)
12
+ x, y = str.split(',').map { |n| BigDecimal.new(n) }
13
+ Trustworthy::Key.new(x, y)
14
+ end
15
+
11
16
  def initialize(x, y)
12
17
  @x = x
13
18
  @y = y
14
19
  end
20
+
21
+ def to_s
22
+ "#{x.to_s('F')},#{y.to_s('F')}"
23
+ end
15
24
  end
16
25
  end
@@ -2,9 +2,7 @@ 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
5
+ store.ultra_safe = true if store.respond_to?(:ultra_safe=)
8
6
 
9
7
  store.transaction do
10
8
  yield Trustworthy::Settings.new(store)
@@ -17,20 +15,8 @@ module Trustworthy
17
15
 
18
16
  def add_key(key, username, password)
19
17
  salt = SCrypt::Engine.generate_salt
20
-
21
- cipher = _cipher_from_password(salt, password)
22
- nonce = Trustworthy::Cipher.generate_nonce
23
- plaintext = "#{key.x.to_s('F')},#{key.y.to_s('F')}"
24
- ciphertext = cipher.encrypt(nonce, '', plaintext)
25
-
26
- encrypted_point = [nonce, ciphertext].map do |field|
27
- Base64.encode64(field).gsub("\n", '')
28
- end.join('--')
29
-
30
- @store[username] = {
31
- 'salt' => salt,
32
- 'encrypted_point' => encrypted_point
33
- }
18
+ encrypted_point = _encrypt(key.to_s, salt, password)
19
+ @store[username] = {'salt' => salt, 'encrypted_point' => encrypted_point}
34
20
  end
35
21
 
36
22
  def empty?
@@ -53,15 +39,8 @@ module Trustworthy
53
39
  key = find_key(username)
54
40
  salt = key['salt']
55
41
  ciphertext = key['encrypted_point']
56
-
57
- nonce, ciphertext = ciphertext.split('--').map do |field|
58
- Base64.decode64(field)
59
- end
60
-
61
- cipher = _cipher_from_password(salt, password)
62
- plaintext = cipher.decrypt(nonce, '', ciphertext)
63
- x, y = plaintext.split(',').map { |n| BigDecimal.new(n) }
64
- Trustworthy::Key.new(x, y)
42
+ plaintext = _decrypt(ciphertext, salt, password)
43
+ Trustworthy::Key.create_from_string(plaintext)
65
44
  end
66
45
 
67
46
  def _cipher_from_password(salt, password)
@@ -69,5 +48,22 @@ module Trustworthy
69
48
  key = SCrypt::Engine.scrypt(password, salt, cost, Trustworthy::Cipher.key_len)
70
49
  Trustworthy::Cipher.new(key)
71
50
  end
51
+
52
+ def _decrypt(ciphertext, salt, password)
53
+ cipher = _cipher_from_password(salt, password)
54
+ nonce, ciphertext = ciphertext.split('--').map do |field|
55
+ Base64.decode64(field)
56
+ end
57
+ cipher.decrypt(nonce, '', ciphertext)
58
+ end
59
+
60
+ def _encrypt(plaintext, salt, password)
61
+ cipher = _cipher_from_password(salt, password)
62
+ nonce = Trustworthy::Cipher.generate_nonce
63
+ ciphertext = cipher.encrypt(nonce, '', plaintext)
64
+ [nonce, ciphertext].map do |field|
65
+ Base64.encode64(field).gsub("\n", '')
66
+ end.join('--')
67
+ end
72
68
  end
73
69
  end
@@ -1,3 +1,3 @@
1
1
  module Trustworthy
2
- VERSION = '0.3.1'
2
+ VERSION = '0.3.2'
3
3
  end
@@ -37,7 +37,7 @@ describe Trustworthy::CLI::Decrypt do
37
37
  'user2',
38
38
  'password2'
39
39
  ) do
40
- decrypt = Trustworthy::CLI::Encrypt.new
40
+ decrypt = Trustworthy::CLI::Decrypt.new
41
41
  decrypt.should_receive(:print_help)
42
42
  decrypt.run([])
43
43
  end
@@ -50,10 +50,20 @@ describe Trustworthy::CLI::Decrypt do
50
50
  'user2',
51
51
  'password2'
52
52
  ) do
53
- decrypt = Trustworthy::CLI::Encrypt.new
53
+ decrypt = Trustworthy::CLI::Decrypt.new
54
54
  decrypt.should_receive(:print_help)
55
55
  decrypt.run(['-i', 'input.txt'])
56
56
  end
57
57
  end
58
+
59
+ it 'should error on non-trustworthy input files' do
60
+ File.open('input.txt', 'w+') do |file|
61
+ file.write('bad file')
62
+ end
63
+
64
+ decrypt = Trustworthy::CLI::Decrypt.new
65
+ decrypt.should_receive(:say).with('File input.txt does not appear to be a trustworthy encrypted file')
66
+ decrypt.run(['-i', 'input.txt', '-o', 'output.txt'])
67
+ end
58
68
  end
59
69
  end
@@ -8,4 +8,21 @@ describe Trustworthy::Key do
8
8
  key.y.should == 84
9
9
  end
10
10
  end
11
+
12
+ describe 'self.create_from_string' do
13
+ it 'should create a key from the string representation' do
14
+ key = Trustworthy::Key.create_from_string('4.0,5.0')
15
+ key.x.should == BigDecimal.new('4.0')
16
+ key.y.should == BigDecimal.new('5.0')
17
+ end
18
+ end
19
+
20
+ describe 'to_s' do
21
+ it 'should return a set of points' do
22
+ x = BigDecimal.new('4')
23
+ y = BigDecimal.new('5')
24
+ key = Trustworthy::Key.new(x, y)
25
+ key.to_s.should == '4.0,5.0'
26
+ end
27
+ end
11
28
  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.1
4
+ version: 0.3.2
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-05-06 00:00:00.000000000 Z
11
+ date: 2013-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aead
@@ -120,6 +120,7 @@ extra_rdoc_files: []
120
120
  files:
121
121
  - lib/trustworthy/cli/add_key.rb
122
122
  - lib/trustworthy/cli/command.rb
123
+ - lib/trustworthy/cli/crypt.rb
123
124
  - lib/trustworthy/cli/decrypt.rb
124
125
  - lib/trustworthy/cli/encrypt.rb
125
126
  - lib/trustworthy/cli/init.rb
@@ -143,6 +144,7 @@ files:
143
144
  - spec/trustworthy/settings_spec.rb
144
145
  - bin/trustworthy
145
146
  - README.md
147
+ - LICENSE
146
148
  homepage: http://github.com/jtdowney/trustworthy
147
149
  licenses:
148
150
  - MIT
@@ -163,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
163
165
  version: '0'
164
166
  requirements: []
165
167
  rubyforge_project:
166
- rubygems_version: 2.0.3
168
+ rubygems_version: 2.0.2
167
169
  signing_key:
168
170
  specification_version: 4
169
171
  summary: Encrypt and decrypt files with multiple key holders
@@ -178,3 +180,4 @@ test_files:
178
180
  - spec/trustworthy/prompt_spec.rb
179
181
  - spec/trustworthy/random_spec.rb
180
182
  - spec/trustworthy/settings_spec.rb
183
+ has_rdoc: