trustworthy 0.5.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d5a9bbf0d74ba49411469bfe883a73ffb5062f7
4
- data.tar.gz: 1310654f1209695a8d5a55fa6fb93a8ac154085a
3
+ metadata.gz: 2e1a1390b6d8e5000c0878ac62d61b3681f49c01
4
+ data.tar.gz: 145879b2c660ca53e418a7f7601274afbf5a0c5b
5
5
  SHA512:
6
- metadata.gz: 53d3ef8231eeba640b3a6de17fc7483cab5bbe787cba4a4b6560d2eede988c0918cd8966d0d319192660e4d25ed0dca9af63f0a630e6b0d54572db21fa82caa2
7
- data.tar.gz: 11b1cba0bae7bd711ddf38a8427cf87d7fd2104d99540070b348c7504a3defa7307f7ff0d2db02cae2f57142ac505568efd4fb5b3ea1b4f9cd17d2b6a5edfd79
6
+ metadata.gz: a40f4302c2b41ed837799d9fa330a7ceb22ec0d2cbb200608b36d7fde321d568091cb33c1b47795f6b3fa9410f37dd9ca9537977c851acc69ac817bc1e1f31fe
7
+ data.tar.gz: 1b2b475e1480479be4ff8bef09b7993cc181b04fac342e68e8732fe712beac7ae3be8138b4393dd220b1f99de4c2608271333076e1aa206dd8d9c7f104e35e2a
@@ -16,11 +16,11 @@ require 'trustworthy/settings'
16
16
  require 'trustworthy/version'
17
17
 
18
18
  module Trustworthy
19
- CipherAlgorithm = 'AES-256-CBC-HMAC-SHA-256'
19
+ CipherAlgorithm = 'AES-256-CBC-HMAC-SHA-256'.freeze
20
20
  Cipher = AEAD::Cipher.new(CipherAlgorithm)
21
21
  SCryptParams = {
22
- :max_time => 5,
23
- :max_memfrac => 0.75,
24
- :max_mem => 16 * 1024 * 1024,
25
- }
22
+ max_time: 5,
23
+ max_memfrac: 0.75,
24
+ max_mem: 16 * 1024 * 1024
25
+ }.freeze
26
26
  end
@@ -19,8 +19,8 @@ module Trustworthy
19
19
  'init' => Trustworthy::CLI::Init,
20
20
  'decrypt' => Trustworthy::CLI::Decrypt,
21
21
  'encrypt' => Trustworthy::CLI::Encrypt,
22
- 'passwd' => Trustworthy::CLI::Passwd,
23
- }
22
+ 'passwd' => Trustworthy::CLI::Passwd
23
+ }.freeze
24
24
 
25
25
  def self.banner
26
26
  "Trustworthy CLI v#{Trustworthy::VERSION}"
@@ -28,7 +28,7 @@ module Trustworthy
28
28
 
29
29
  def run(args)
30
30
  command = args.shift
31
- if Commands.has_key?(command)
31
+ if Commands.key?(command)
32
32
  klass = Commands[command]
33
33
  klass.new.run(args)
34
34
  else
@@ -40,7 +40,7 @@ module Trustworthy
40
40
  say("#{Trustworthy::CLI.banner}\n\n")
41
41
  say('Commands:')
42
42
  Commands.each do |name, klass|
43
- say(' %-8s %s' % [name, klass.description])
43
+ say(format(' %-8s %s', name, klass.description))
44
44
  end
45
45
  say("\nSee 'trustworthy <command> --help' for more information on a specific command")
46
46
  end
@@ -2,7 +2,7 @@ module Trustworthy
2
2
  class CLI
3
3
  module Command
4
4
  def default_options
5
- { :config_file => 'trustworthy.yml' }
5
+ {config_file: 'trustworthy.yml'}
6
6
  end
7
7
 
8
8
  def parse_options(command, args)
@@ -27,9 +27,7 @@ module Trustworthy
27
27
  end
28
28
 
29
29
  def print_help
30
- if @parser
31
- puts @parser
32
- end
30
+ puts @parser if @parser
33
31
  end
34
32
 
35
33
  def say(message)
@@ -6,9 +6,9 @@ module Trustworthy
6
6
  end
7
7
 
8
8
  def parse_options(args)
9
- options = super(_command, args) do |opts, options|
9
+ options = super(_command, args) do |opts, inner_options|
10
10
  opts.on('-o', '--output FILE', "File to write #{_command}ed contents to") do |file|
11
- options[:output_file] = file
11
+ inner_options[:output_file] = file
12
12
  end
13
13
  end
14
14
  options[:input_file] = args.shift
@@ -10,7 +10,7 @@ module Trustworthy
10
10
 
11
11
  def parse_options(args)
12
12
  options = super(args)
13
- if options[:input_file].to_s.end_with?('.tw') && !options.has_key?(:output_file)
13
+ if options[:input_file].to_s.end_with?('.tw') && !options.key?(:output_file)
14
14
  options[:output_file] = File.basename(options[:input_file], '.tw')
15
15
  end
16
16
  options
@@ -34,10 +34,10 @@ module Trustworthy
34
34
  end
35
35
 
36
36
  def _strip_ciphertext(ciphertext)
37
- ciphertext.
38
- gsub(/-+(BEGIN|END) TRUSTWORTHY ENCRYPTED FILE-+/, '').
39
- gsub(/^Version: .*$/, '').
40
- gsub("\n", '')
37
+ ciphertext
38
+ .gsub(/-+(BEGIN|END) TRUSTWORTHY ENCRYPTED FILE-+/, '')
39
+ .gsub(/^Version: .*$/, '')
40
+ .delete("\n")
41
41
  end
42
42
  end
43
43
  end
@@ -10,7 +10,7 @@ module Trustworthy
10
10
 
11
11
  def parse_options(args)
12
12
  options = super(args)
13
- unless options.has_key?(:output_file)
13
+ unless options.key?(:output_file)
14
14
  options[:output_file] = "#{options[:input_file]}.tw"
15
15
  end
16
16
  options
@@ -8,7 +8,7 @@ module Trustworthy
8
8
  end
9
9
 
10
10
  def default_options
11
- { :keys => 2 }.merge(super)
11
+ {keys: 2}.merge(super)
12
12
  end
13
13
 
14
14
  def parse_options(args)
@@ -19,6 +19,7 @@ module Trustworthy
19
19
  end
20
20
  end
21
21
 
22
+ # rubocop:disable Metrics/AbcSize
22
23
  def run(args)
23
24
  options = parse_options(args)
24
25
 
@@ -30,7 +31,7 @@ module Trustworthy
30
31
  Trustworthy::Settings.open(options[:config_file]) do |settings|
31
32
  unless settings.empty?
32
33
  say("Config #{options[:config_file]} already exists")
33
- return
34
+ return # rubocop:disable Lint/NonLocalExitFromIterator
34
35
  end
35
36
  end
36
37
 
@@ -9,7 +9,7 @@ module Trustworthy
9
9
  end
10
10
 
11
11
  def self.create_from_string(str)
12
- x, y = str.split(',').map { |n| BigDecimal.new(n) }
12
+ x, y = str.split(',').map { |n| BigDecimal(n) }
13
13
  Trustworthy::Key.new(x, y)
14
14
  end
15
15
 
@@ -32,7 +32,7 @@ module Trustworthy
32
32
  ciphertext = _cipher.encrypt(nonce, '', plaintext)
33
33
 
34
34
  [nonce, ciphertext].map do |field|
35
- Base64.encode64(field).gsub("\n", '')
35
+ Base64.strict_encode64(field)
36
36
  end.join('--')
37
37
  end
38
38
 
@@ -12,15 +12,12 @@ module Trustworthy
12
12
  username = nil
13
13
  loop do
14
14
  username = _ask('Username: ')
15
- if settings.has_key?(username)
16
- _error("Key #{username} is already in use")
17
- else
18
- break
19
- end
15
+ break unless settings.key?(username)
16
+ _error("Key #{username} is already in use")
20
17
  end
21
18
 
22
19
  loop do
23
- password = _ask_password('Password: ')
20
+ password = _ask_password_with_strength_requirements('Password: ')
24
21
  password_confirm = _ask_password('Password (again): ')
25
22
  if password == password_confirm
26
23
  settings.add_key(key, username, password)
@@ -39,7 +36,7 @@ module Trustworthy
39
36
  username, key = _unlock_key(settings, [])
40
37
 
41
38
  loop do
42
- password = _ask_password('Password: ')
39
+ password = _ask_password_with_strength_requirements('Password: ')
43
40
  password_confirm = _ask_password('Password (again): ')
44
41
  if password == password_confirm
45
42
  settings.add_key(key, username, password)
@@ -61,7 +58,7 @@ module Trustworthy
61
58
  username1, key1 = _unlock_key(settings, usernames_in_use)
62
59
  usernames_in_use << username1
63
60
 
64
- username2, key2 = _unlock_key(settings, usernames_in_use)
61
+ _, key2 = _unlock_key(settings, usernames_in_use)
65
62
 
66
63
  master_key = Trustworthy::MasterKey.create_from_keys(key1, key2)
67
64
  _say('Reconstructed master key')
@@ -70,7 +67,7 @@ module Trustworthy
70
67
  end
71
68
  end
72
69
 
73
- def _unlock_key(settings, usernames_in_use)
70
+ def _unlock_key(settings, usernames_in_use) # rubocop:disable Metrics/MethodLength
74
71
  username = nil
75
72
  loop do
76
73
  username = _ask('Username: ')
@@ -105,10 +102,26 @@ module Trustworthy
105
102
  @terminal.ask(question) { |q| q.echo = false }.to_s
106
103
  end
107
104
 
105
+ def _ask_password_with_strength_requirements(question)
106
+ loop do
107
+ password = @terminal.ask(question) { |q| q.echo = false }.to_s
108
+ return password if _strong_password?(password)
109
+ _error('Password is too weak')
110
+ end
111
+ end
112
+
108
113
  def _say(message)
109
114
  @terminal.say(message)
110
115
  end
111
116
 
117
+ def _strong_password?(password)
118
+ return false unless password =~ /.{8,}/
119
+ return false unless password =~ /[0-9]/
120
+ return false unless password =~ /[A-Za-z]/
121
+ return false unless password =~ /\W/
122
+ true
123
+ end
124
+
112
125
  def _error(message)
113
126
  colored_message = @terminal.color(message, :error)
114
127
  _say(colored_message)
@@ -3,7 +3,7 @@ module Trustworthy
3
3
  def self.number(size = 32)
4
4
  raw_bytes = bytes(size)
5
5
  number = raw_bytes.unpack('H*').first.hex
6
- BigDecimal.new(number.to_s)
6
+ BigDecimal(number.to_s)
7
7
  end
8
8
 
9
9
  def self.bytes(size = 32)
@@ -27,7 +27,7 @@ module Trustworthy
27
27
  @store[username]
28
28
  end
29
29
 
30
- def has_key?(username)
30
+ def key?(username)
31
31
  @store.root?(username)
32
32
  end
33
33
 
@@ -62,7 +62,7 @@ module Trustworthy
62
62
  nonce = Trustworthy::Cipher.generate_nonce
63
63
  ciphertext = cipher.encrypt(nonce, '', plaintext)
64
64
  [nonce, ciphertext].map do |field|
65
- Base64.encode64(field).gsub("\n", '')
65
+ Base64.strict_encode64(field)
66
66
  end.join('--')
67
67
  end
68
68
  end
@@ -1,3 +1,3 @@
1
1
  module Trustworthy
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'.freeze
3
3
  end
@@ -5,23 +5,27 @@ require 'timecop'
5
5
  require 'highline/simulate'
6
6
 
7
7
  module TestValues
8
- SettingsFile = 'trustworthy.yml'
8
+ SettingsFile = 'trustworthy.yml'.freeze
9
9
  InitializationVector = ['39164ec082fb8b7336d3c5500af99dcb'].pack('H*')
10
- Plaintext = 'the chair is against the wall'
11
- Ciphertext = 'ORZOwIL7i3M208VQCvmdyw==--b16sXYF6ZbisfF7YBpHbNpBOHOYToQV9gHs3En2SeksKmhuVHvV2/Jqe3KDvW4PiuuhQqLO3m/7d/4ktGUHUOQ=='
12
- Salt = '400$8$1b$3e31f076a3226825'
13
- MasterKey = Trustworthy::MasterKey.new(BigDecimal.new('1'), BigDecimal.new('5'))
14
- EncryptedPoint = 'ORZOwIL7i3M208VQCvmdyw==--F9LmBJbtVT36tLBcVoqpJgy45TkwkRyOcYvJfriN70AOXKweTuPRUGCSDCXRNGKF'
15
- EncryptedFile = <<-EOF
10
+ Plaintext = 'the chair is against the wall'.freeze
11
+ Ciphertext = 'ORZOwIL7i3M208VQCvmdyw==--b16sXYF6ZbisfF7YBpHbNpBOHOYToQV9gHs3En2SeksKmhuVHvV2/Jqe3KDvW4PiuuhQqLO3m/7d/4ktGUHUOQ=='.freeze
12
+ Salt = '400$8$1b$3e31f076a3226825'.freeze
13
+ MasterKey = Trustworthy::MasterKey.new(BigDecimal('1'), BigDecimal('5'))
14
+ EncryptedPoint = 'ORZOwIL7i3M208VQCvmdyw==--F9LmBJbtVT36tLBcVoqpJgy45TkwkRyOcYvJfriN70AOXKweTuPRUGCSDCXRNGKF'.freeze
15
+ # rubocop:disable Layout/IndentHeredoc
16
+ EncryptedFile = <<-FILE.freeze
16
17
  -----BEGIN TRUSTWORTHY ENCRYPTED FILE-----
17
18
  Version: Trustworthy/#{Trustworthy::VERSION}
18
19
 
19
20
  ORZOwIL7i3M208VQCvmdyw==--o39ZYHOC+HotoUiBqeHqvSOWXUbXwaZRsMkwzQ
20
21
  7nVtk1jWftqroCoi6QITaiqQlTZywpN7DLqsAWeSKRhXipjA==
21
22
  -----END TRUSTWORTHY ENCRYPTED FILE-----
22
- EOF
23
+ FILE
24
+ # rubocop:enable Layout/IndentHeredoc
23
25
  end
24
26
 
27
+ SCrypt::Engine::DEFAULTS[:cost] = '400$8$1b$'
28
+
25
29
  RSpec.configure do |config|
26
30
  config.order = 'random'
27
31
  config.include TestConstruct::Helpers
@@ -32,7 +36,7 @@ end
32
36
 
33
37
  def create_config(filename)
34
38
  Trustworthy::Settings.open(filename) do |settings|
35
- settings.add_key(TestValues::MasterKey.create_key, 'user1', 'password1')
36
- settings.add_key(TestValues::MasterKey.create_key, 'user2', 'password2')
39
+ settings.add_key(TestValues::MasterKey.create_key, 'user1', 'P@ssw0rd1')
40
+ settings.add_key(TestValues::MasterKey.create_key, 'user2', 'P@ssw0rd2')
37
41
  end
38
42
  end
@@ -17,12 +17,12 @@ describe Trustworthy::CLI::AddKey do
17
17
  it 'should add a new user' do
18
18
  HighLine::Simulate.with(
19
19
  'user1',
20
- 'password1',
20
+ 'P@ssw0rd1',
21
21
  'user2',
22
- 'password2',
22
+ 'P@ssw0rd2',
23
23
  'user3',
24
- 'password3',
25
- 'password3'
24
+ 'P@ssw0rd3',
25
+ 'P@ssw0rd3'
26
26
  ) do
27
27
  Trustworthy::CLI::AddKey.new.run([])
28
28
  end
@@ -20,9 +20,9 @@ describe Trustworthy::CLI::Decrypt do
20
20
  it 'should unlock the master key and decrypt the file' do
21
21
  HighLine::Simulate.with(
22
22
  'user1',
23
- 'password1',
23
+ 'P@ssw0rd1',
24
24
  'user2',
25
- 'password2'
25
+ 'P@ssw0rd2'
26
26
  ) do
27
27
  Trustworthy::CLI::Decrypt.new.run(['input.txt.tw'])
28
28
  end
@@ -35,37 +35,23 @@ describe Trustworthy::CLI::Decrypt do
35
35
  end
36
36
 
37
37
  it 'should require an input file' do
38
- HighLine::Simulate.with(
39
- 'user1',
40
- 'password1',
41
- 'user2',
42
- 'password2'
43
- ) do
44
- decrypt = Trustworthy::CLI::Decrypt.new
45
- expect(decrypt).to receive(:print_help)
46
- decrypt.run([])
47
- end
38
+ decrypt = Trustworthy::CLI::Decrypt.new
39
+ expect(decrypt).to receive(:print_help)
40
+ decrypt.run([])
48
41
  end
49
42
 
50
43
  it 'should require an output file if input does not end in .tw' do
51
- HighLine::Simulate.with(
52
- 'user1',
53
- 'password1',
54
- 'user2',
55
- 'password2'
56
- ) do
57
- decrypt = Trustworthy::CLI::Decrypt.new
58
- expect(decrypt).to receive(:print_help)
59
- decrypt.run(['input.txt'])
60
- end
44
+ decrypt = Trustworthy::CLI::Decrypt.new
45
+ expect(decrypt).to receive(:print_help)
46
+ decrypt.run(['input.txt'])
61
47
  end
62
48
 
63
49
  it 'should take an optional output file' do
64
50
  HighLine::Simulate.with(
65
51
  'user1',
66
- 'password1',
52
+ 'P@ssw0rd1',
67
53
  'user2',
68
- 'password2'
54
+ 'P@ssw0rd2'
69
55
  ) do
70
56
  Trustworthy::CLI::Decrypt.new.run(['input.txt.tw', '-o', 'output.txt'])
71
57
  end
@@ -21,9 +21,9 @@ describe Trustworthy::CLI::Encrypt do
21
21
  it 'should unlock the master key and encrypt the file' do
22
22
  HighLine::Simulate.with(
23
23
  'user1',
24
- 'password1',
24
+ 'P@ssw0rd1',
25
25
  'user2',
26
- 'password2'
26
+ 'P@ssw0rd2'
27
27
  ) do
28
28
  Trustworthy::CLI::Encrypt.new.run(['input.txt'])
29
29
  end
@@ -36,24 +36,17 @@ describe Trustworthy::CLI::Encrypt do
36
36
  end
37
37
 
38
38
  it 'should require an input file' do
39
- HighLine::Simulate.with(
40
- 'user1',
41
- 'password1',
42
- 'user2',
43
- 'password2'
44
- ) do
45
- encrypt = Trustworthy::CLI::Encrypt.new
46
- expect(encrypt).to receive(:print_help)
47
- encrypt.run([])
48
- end
39
+ encrypt = Trustworthy::CLI::Encrypt.new
40
+ expect(encrypt).to receive(:print_help)
41
+ encrypt.run([])
49
42
  end
50
43
 
51
44
  it 'should allow a named output file' do
52
45
  HighLine::Simulate.with(
53
46
  'user1',
54
- 'password1',
47
+ 'P@ssw0rd1',
55
48
  'user2',
56
- 'password2'
49
+ 'P@ssw0rd2'
57
50
  ) do
58
51
  Trustworthy::CLI::Encrypt.new.run(['input.txt', '-o', 'output.txt'])
59
52
  end
@@ -22,11 +22,11 @@ describe Trustworthy::CLI::Init do
22
22
  it 'should write a settings file' do
23
23
  HighLine::Simulate.with(
24
24
  'user1',
25
- 'password1',
26
- 'password1',
25
+ 'P@ssw0rd1',
26
+ 'P@ssw0rd1',
27
27
  'user2',
28
- 'password2',
29
- 'password2'
28
+ 'P@ssw0rd2',
29
+ 'P@ssw0rd2'
30
30
  ) do
31
31
  Trustworthy::CLI::Init.new.run([])
32
32
  end
@@ -43,11 +43,11 @@ describe Trustworthy::CLI::Init do
43
43
  construct.file(filename)
44
44
  HighLine::Simulate.with(
45
45
  'user1',
46
- 'password1',
47
- 'password1',
46
+ 'P@ssw0rd1',
47
+ 'P@ssw0rd1',
48
48
  'user2',
49
- 'password2',
50
- 'password2'
49
+ 'P@ssw0rd2',
50
+ 'P@ssw0rd2'
51
51
  ) do
52
52
  Trustworthy::CLI::Init.new.run(['-c', filename])
53
53
  end
@@ -62,14 +62,14 @@ describe Trustworthy::CLI::Init do
62
62
  it 'should generate the specified number of keys' do
63
63
  HighLine::Simulate.with(
64
64
  'user1',
65
- 'password1',
66
- 'password1',
65
+ 'P@ssw0rd1',
66
+ 'P@ssw0rd1',
67
67
  'user2',
68
- 'password2',
69
- 'password2',
68
+ 'P@ssw0rd2',
69
+ 'P@ssw0rd2',
70
70
  'user3',
71
- 'password3',
72
- 'password3'
71
+ 'P@ssw0rd3',
72
+ 'P@ssw0rd3'
73
73
  ) do
74
74
  Trustworthy::CLI::Init.new.run(['-k', '3'])
75
75
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Trustworthy::Key do
4
4
  describe 'self.create' do
5
5
  it 'should create a key along the slope and intercept' do
6
- allow(Trustworthy::Random).to receive(:number).and_return(BigDecimal.new('10'))
6
+ allow(Trustworthy::Random).to receive(:number).and_return(BigDecimal('10'))
7
7
  key = Trustworthy::Key.create(6, 24)
8
8
  expect(key.y).to eq(84)
9
9
  end
@@ -12,15 +12,15 @@ describe Trustworthy::Key do
12
12
  describe 'self.create_from_string' do
13
13
  it 'should create a key from the string representation' do
14
14
  key = Trustworthy::Key.create_from_string('4.0,5.0')
15
- expect(key.x).to eq(BigDecimal.new('4.0'))
16
- expect(key.y).to eq(BigDecimal.new('5.0'))
15
+ expect(key.x).to eq(BigDecimal('4.0'))
16
+ expect(key.y).to eq(BigDecimal('5.0'))
17
17
  end
18
18
  end
19
19
 
20
20
  describe 'to_s' do
21
21
  it 'should return a set of points' do
22
- x = BigDecimal.new('4')
23
- y = BigDecimal.new('5')
22
+ x = BigDecimal('4')
23
+ y = BigDecimal('5')
24
24
  key = Trustworthy::Key.new(x, y)
25
25
  expect(key.to_s).to eq('4.0,5.0')
26
26
  end
@@ -30,7 +30,7 @@ describe Trustworthy::MasterKey do
30
30
 
31
31
  describe 'self.create' do
32
32
  it 'should generate a random slope and intercept' do
33
- allow(Trustworthy::Random).to receive(:number).and_return(BigDecimal.new('10'))
33
+ allow(Trustworthy::Random).to receive(:number).and_return(BigDecimal('10'))
34
34
 
35
35
  master_key = Trustworthy::MasterKey.create
36
36
  key = master_key.create_key
@@ -41,10 +41,10 @@ describe Trustworthy::MasterKey do
41
41
 
42
42
  describe 'self.create_from_keys' do
43
43
  it 'should calculate the slope and intercept given two keys' do
44
- allow(Trustworthy::Random).to receive(:number).and_return(BigDecimal.new('10'))
44
+ allow(Trustworthy::Random).to receive(:number).and_return(BigDecimal('10'))
45
45
 
46
- key1 = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('30'))
47
- key2 = Trustworthy::Key.new(BigDecimal.new('5'), BigDecimal.new('60'))
46
+ key1 = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('30'))
47
+ key2 = Trustworthy::Key.new(BigDecimal('5'), BigDecimal('60'))
48
48
 
49
49
  master_key = Trustworthy::MasterKey.create_from_keys(key1, key2)
50
50
  new_key = master_key.create_key
@@ -55,7 +55,7 @@ describe Trustworthy::MasterKey do
55
55
 
56
56
  describe 'create_key' do
57
57
  it 'should define a new key' do
58
- master_key = Trustworthy::MasterKey.new(BigDecimal.new('6'), BigDecimal.new('24'))
58
+ master_key = Trustworthy::MasterKey.new(BigDecimal('6'), BigDecimal('24'))
59
59
  key = master_key.create_key
60
60
  expect(key.x).to_not eq(0)
61
61
  expect(key.y).to_not eq(0)
@@ -66,7 +66,7 @@ describe Trustworthy::MasterKey do
66
66
  it 'should encrypt and sign the data using the intercept' do
67
67
  allow(AEAD::Cipher::AES_256_CBC_HMAC_SHA_256).to receive(:generate_nonce).and_return(TestValues::InitializationVector)
68
68
 
69
- master_key = Trustworthy::MasterKey.new(BigDecimal.new('6'), BigDecimal.new('24'))
69
+ master_key = Trustworthy::MasterKey.new(BigDecimal('6'), BigDecimal('24'))
70
70
  ciphertext = master_key.encrypt(TestValues::Plaintext)
71
71
  expect(ciphertext).to eq(TestValues::Ciphertext)
72
72
  end
@@ -74,17 +74,16 @@ describe Trustworthy::MasterKey do
74
74
 
75
75
  describe 'decrypt' do
76
76
  it 'should decrypt and verify the data using the intercept' do
77
- master_key = Trustworthy::MasterKey.new(BigDecimal.new('6'), BigDecimal.new('24'))
77
+ master_key = Trustworthy::MasterKey.new(BigDecimal('6'), BigDecimal('24'))
78
78
  plaintext = master_key.decrypt(TestValues::Ciphertext)
79
79
  expect(plaintext).to eq(TestValues::Plaintext)
80
80
  end
81
81
 
82
82
  it 'should raise an invalid signature error if signatures do not match' do
83
- master_key = Trustworthy::MasterKey.new(BigDecimal.new('6'), BigDecimal.new('24'))
83
+ master_key = Trustworthy::MasterKey.new(BigDecimal('6'), BigDecimal('24'))
84
84
  ciphertext = TestValues::Ciphertext.dup
85
85
  ciphertext[0] = ciphertext[0].next
86
86
  expect { master_key.decrypt(ciphertext) }.to raise_error(ArgumentError, 'ciphertext failed authentication step')
87
87
  end
88
88
  end
89
89
  end
90
-
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Trustworthy::Prompt do
4
- let(:test_key) { Trustworthy::Key.new(BigDecimal.new('1'), BigDecimal.new('2')) }
4
+ let(:test_key) { Trustworthy::Key.new(BigDecimal('1'), BigDecimal('2')) }
5
5
 
6
6
  before(:each) do
7
7
  allow($terminal).to receive(:say)
@@ -19,8 +19,8 @@ describe Trustworthy::Prompt do
19
19
  it 'should prompt for two user keys' do
20
20
  HighLine::Simulate.with(
21
21
  'user3',
22
- 'password',
23
- 'password'
22
+ 'P@ssw0rd',
23
+ 'P@ssw0rd'
24
24
  ) do
25
25
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
26
26
  username = prompt.add_user_key(test_key)
@@ -31,10 +31,10 @@ describe Trustworthy::Prompt do
31
31
  it 'should confirm passwords' do
32
32
  HighLine::Simulate.with(
33
33
  'user3',
34
- 'password1',
35
- 'password2',
36
- 'password1',
37
- 'password1'
34
+ 'P@ssw0rd1',
35
+ 'P@ssw0rd1',
36
+ 'P@ssw0rd2',
37
+ 'P@ssw0rd2'
38
38
  ) do
39
39
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
40
40
  username = prompt.add_user_key(test_key)
@@ -48,8 +48,8 @@ describe Trustworthy::Prompt do
48
48
  HighLine::Simulate.with(
49
49
  'user1',
50
50
  'user3',
51
- 'password',
52
- 'password'
51
+ 'P@ssw0rd',
52
+ 'P@ssw0rd'
53
53
  ) do
54
54
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
55
55
  expect(prompt).to receive(:_error).with('Key user1 is already in use')
@@ -57,15 +57,30 @@ describe Trustworthy::Prompt do
57
57
  expect(username).to eq('user3')
58
58
  end
59
59
  end
60
+
61
+ it 'should enforce strong passwords' do
62
+ create_config(TestValues::SettingsFile)
63
+
64
+ HighLine::Simulate.with(
65
+ 'user3',
66
+ 'password',
67
+ 'P@ssw0rd',
68
+ 'P@ssw0rd'
69
+ ) do
70
+ prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
71
+ expect(prompt).to receive(:_error).with('Password is too weak')
72
+ prompt.add_user_key(test_key)
73
+ end
74
+ end
60
75
  end
61
76
 
62
77
  describe 'unlock_master_key' do
63
78
  it 'should prompt for two user keys' do
64
79
  HighLine::Simulate.with(
65
80
  'user1',
66
- 'password1',
81
+ 'P@ssw0rd1',
67
82
  'user2',
68
- 'password2'
83
+ 'P@ssw0rd2'
69
84
  ) do
70
85
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
71
86
  master_key = prompt.unlock_master_key
@@ -88,10 +103,10 @@ describe Trustworthy::Prompt do
88
103
  it 'should require two distinct keys to unlock' do
89
104
  HighLine::Simulate.with(
90
105
  'user1',
91
- 'password1',
106
+ 'P@ssw0rd1',
92
107
  'user1',
93
108
  'user2',
94
- 'password2'
109
+ 'P@ssw0rd2'
95
110
  ) do
96
111
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
97
112
  expect(prompt).to receive(:_error).with('Key user1 is already in use')
@@ -103,9 +118,9 @@ describe Trustworthy::Prompt do
103
118
  HighLine::Simulate.with(
104
119
  'missing',
105
120
  'user1',
106
- 'password1',
121
+ 'P@ssw0rd1',
107
122
  'user2',
108
- 'password2'
123
+ 'P@ssw0rd2'
109
124
  ) do
110
125
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
111
126
  expect(prompt).to receive(:_error).with('Key missing does not exist')
@@ -116,10 +131,10 @@ describe Trustworthy::Prompt do
116
131
  it 'should require an existing user for the second key' do
117
132
  HighLine::Simulate.with(
118
133
  'user1',
119
- 'password1',
134
+ 'P@ssw0rd1',
120
135
  'missing',
121
136
  'user2',
122
- 'password2'
137
+ 'P@ssw0rd2'
123
138
  ) do
124
139
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
125
140
  expect(prompt).to receive(:_error).with('Key missing does not exist')
@@ -131,9 +146,9 @@ describe Trustworthy::Prompt do
131
146
  HighLine::Simulate.with(
132
147
  'user1',
133
148
  'bad_password',
134
- 'password1',
149
+ 'P@ssw0rd1',
135
150
  'user2',
136
- 'password2'
151
+ 'P@ssw0rd2'
137
152
  ) do
138
153
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
139
154
  expect(prompt).to receive(:_error).with('Password incorrect for user1')
@@ -144,10 +159,10 @@ describe Trustworthy::Prompt do
144
159
  it 'should prompt for the correct password for the second key' do
145
160
  HighLine::Simulate.with(
146
161
  'user1',
147
- 'password1',
162
+ 'P@ssw0rd1',
148
163
  'user2',
149
164
  'bad_password',
150
- 'password2'
165
+ 'P@ssw0rd2'
151
166
  ) do
152
167
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
153
168
  expect(prompt).to receive(:_error).with('Password incorrect for user2')
@@ -161,9 +176,9 @@ describe Trustworthy::Prompt do
161
176
  old_settings = YAML.load_file(TestValues::SettingsFile)
162
177
  HighLine::Simulate.with(
163
178
  'user1',
164
- 'password1',
165
- 'password2',
166
- 'password2',
179
+ 'P@ssw0rd1',
180
+ 'P@ssw0rd2',
181
+ 'P@ssw0rd2'
167
182
  ) do
168
183
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
169
184
  prompt.change_user_password
@@ -177,9 +192,9 @@ describe Trustworthy::Prompt do
177
192
  HighLine::Simulate.with(
178
193
  'user1',
179
194
  'bad_password',
180
- 'password1',
181
- 'password2',
182
- 'password2',
195
+ 'P@ssw0rd1',
196
+ 'P@ssw0rd2',
197
+ 'P@ssw0rd2'
183
198
  ) do
184
199
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
185
200
  expect(prompt).to receive(:_error).with('Password incorrect for user1')
@@ -191,11 +206,11 @@ describe Trustworthy::Prompt do
191
206
  old_settings = YAML.load_file(TestValues::SettingsFile)
192
207
  HighLine::Simulate.with(
193
208
  'user1',
194
- 'password1',
195
- 'password2',
196
- 'password3',
197
- 'password2',
198
- 'password2',
209
+ 'P@ssw0rd1',
210
+ 'P@ssw0rd2',
211
+ 'P@ssw0rd3',
212
+ 'P@ssw0rd2',
213
+ 'P@ssw0rd2'
199
214
  ) do
200
215
  prompt = Trustworthy::Prompt.new(TestValues::SettingsFile, $terminal)
201
216
  prompt.change_user_password
@@ -9,7 +9,7 @@ describe Trustworthy::Random do
9
9
 
10
10
  it 'should return a number up to a given byte size' do
11
11
  random = Trustworthy::Random.number(2)
12
- expect(random).to be <= 2 ** 16
12
+ expect(random).to be <= 2**16
13
13
  end
14
14
  end
15
15
 
@@ -16,7 +16,7 @@ describe Trustworthy::Settings do
16
16
  it 'should read and write the key information to a file' do
17
17
  Timecop.freeze(DateTime.new(2017, 10, 19, 9, 0, 0, 0)) do
18
18
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
19
- key = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('3'))
19
+ key = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('3'))
20
20
  settings.add_key(key, 'user', 'password1')
21
21
  end
22
22
 
@@ -32,13 +32,13 @@ describe Trustworthy::Settings do
32
32
 
33
33
  it 'should preserve the contents if an exception is raised' do
34
34
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
35
- key = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('3'))
35
+ key = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('3'))
36
36
  settings.add_key(key, 'user', 'password1')
37
37
  end
38
38
 
39
39
  expect do
40
40
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
41
- key = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('3'))
41
+ key = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('3'))
42
42
  settings.add_key(key, 'user', 'password2')
43
43
  settings.add_key(key, 'missing', 'password')
44
44
  raise 'boom'
@@ -57,9 +57,9 @@ describe Trustworthy::Settings do
57
57
  end
58
58
 
59
59
  describe 'add_key' do
60
- it 'should encrypt the key with the password' do |settings|
60
+ it 'should encrypt the key with the password' do
61
61
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
62
- key = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('3'))
62
+ key = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('3'))
63
63
  settings.add_key(key, 'user', 'password1')
64
64
  found_key = settings.find_key('user')
65
65
  expect(found_key['salt']).to eq(TestValues::Salt)
@@ -71,15 +71,15 @@ describe Trustworthy::Settings do
71
71
  describe 'has_key?' do
72
72
  it 'should be true if the key exists' do
73
73
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
74
- key = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('3'))
74
+ key = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('3'))
75
75
  settings.add_key(key, 'user', 'password1')
76
- expect(settings).to have_key('user')
76
+ expect(settings.key?('user')).to be_truthy
77
77
  end
78
78
  end
79
79
 
80
80
  it 'should be false if the key does exists' do
81
81
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
82
- expect(settings).to_not have_key('missing')
82
+ expect(settings.key?('missing')).to_not be_truthy
83
83
  end
84
84
  end
85
85
  end
@@ -93,7 +93,7 @@ describe Trustworthy::Settings do
93
93
 
94
94
  it 'should not be recoverable with one user key' do
95
95
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
96
- key = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('3'))
96
+ key = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('3'))
97
97
  settings.add_key(key, 'user', 'password')
98
98
  expect(settings).to_not be_recoverable
99
99
  end
@@ -101,8 +101,8 @@ describe Trustworthy::Settings do
101
101
 
102
102
  it 'should be recoverable with two or more user keys' do
103
103
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
104
- key1 = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('3'))
105
- key2 = Trustworthy::Key.new(BigDecimal.new('3'), BigDecimal.new('4'))
104
+ key1 = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('3'))
105
+ key2 = Trustworthy::Key.new(BigDecimal('3'), BigDecimal('4'))
106
106
  settings.add_key(key1, 'user1', 'password')
107
107
  settings.add_key(key2, 'user2', 'password')
108
108
  expect(settings).to be_recoverable
@@ -113,11 +113,11 @@ describe Trustworthy::Settings do
113
113
  describe 'unlock_key' do
114
114
  it 'should decrypt the key with the password' do
115
115
  Trustworthy::Settings.open(TestValues::SettingsFile) do |settings|
116
- key = Trustworthy::Key.new(BigDecimal.new('2'), BigDecimal.new('3'))
116
+ key = Trustworthy::Key.new(BigDecimal('2'), BigDecimal('3'))
117
117
  settings.add_key(key, 'user', 'password1')
118
118
  unlocked_key = settings.unlock_key('user', 'password1')
119
- expect(unlocked_key.x).to eq(BigDecimal.new('2'))
120
- expect(unlocked_key.y).to eq(BigDecimal.new('3'))
119
+ expect(unlocked_key.x).to eq(BigDecimal('2'))
120
+ expect(unlocked_key.y).to eq(BigDecimal('3'))
121
121
  end
122
122
  end
123
123
  end
metadata CHANGED
@@ -1,130 +1,144 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trustworthy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Downey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-19 00:00:00.000000000 Z
11
+ date: 2018-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aead
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: highline
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.7'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.7'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: hkdf
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: 0.3.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.3.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: scrypt
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '3.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: test_construct
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 2.0.1
75
+ version: 12.1.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 2.0.1
82
+ version: 12.1.0
83
83
  - !ruby/object:Gem::Dependency
84
- name: timecop
84
+ name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.9.1
89
+ version: 3.7.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.9.1
96
+ version: 3.7.0
97
97
  - !ruby/object:Gem::Dependency
98
- name: rspec
98
+ name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 3.7.0
103
+ version: 0.50.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 3.7.0
110
+ version: 0.50.0
111
111
  - !ruby/object:Gem::Dependency
112
- name: rake
112
+ name: test_construct
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 12.1.0
117
+ version: 2.0.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 12.1.0
125
- description: Implements a special case (k = 2) of Adi Shamir's secret sharing algorithm.
126
- This allows secret files to be encrypted on disk and require two secret holders
127
- to decrypt it.
124
+ version: 2.0.1
125
+ - !ruby/object:Gem::Dependency
126
+ name: timecop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 0.9.1
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 0.9.1
139
+ description: |-
140
+ Implements a special case (k = 2) of Adi Shamir's secret sharing algorithm.
141
+ This allows secret files to be encrypted on disk and require two secret holders to decrypt it.
128
142
  email:
129
143
  - jdowney@gmail.com
130
144
  executables:
@@ -170,28 +184,28 @@ require_paths:
170
184
  - lib
171
185
  required_ruby_version: !ruby/object:Gem::Requirement
172
186
  requirements:
173
- - - ">="
187
+ - - '>='
174
188
  - !ruby/object:Gem::Version
175
189
  version: '0'
176
190
  required_rubygems_version: !ruby/object:Gem::Requirement
177
191
  requirements:
178
- - - ">="
192
+ - - '>='
179
193
  - !ruby/object:Gem::Version
180
194
  version: '0'
181
195
  requirements: []
182
196
  rubyforge_project:
183
- rubygems_version: 2.6.13
197
+ rubygems_version: 2.6.14
184
198
  signing_key:
185
199
  specification_version: 4
186
200
  summary: Encrypt and decrypt files with multiple key holders
187
201
  test_files:
188
- - spec/spec_helper.rb
189
- - spec/trustworthy/cli/add_key_spec.rb
202
+ - spec/trustworthy/master_key_spec.rb
203
+ - spec/trustworthy/prompt_spec.rb
204
+ - spec/trustworthy/cli/init_spec.rb
190
205
  - spec/trustworthy/cli/decrypt_spec.rb
206
+ - spec/trustworthy/cli/add_key_spec.rb
191
207
  - spec/trustworthy/cli/encrypt_spec.rb
192
- - spec/trustworthy/cli/init_spec.rb
193
208
  - spec/trustworthy/key_spec.rb
194
- - spec/trustworthy/master_key_spec.rb
195
- - spec/trustworthy/prompt_spec.rb
196
- - spec/trustworthy/random_spec.rb
197
209
  - spec/trustworthy/settings_spec.rb
210
+ - spec/trustworthy/random_spec.rb
211
+ - spec/spec_helper.rb