trustworthy 0.5.0 → 0.6.0

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: 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