duse 0.0.7 → 0.0.8

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.
@@ -1,6 +1,7 @@
1
1
  require 'duse/cli/secret_add'
2
2
  require 'duse/cli/secret_get'
3
3
  require 'duse/cli/secret_list'
4
+ require 'duse/cli/secret_tree'
4
5
  require 'duse/cli/secret_remove'
5
6
  require 'duse/cli/secret_update'
6
7
 
@@ -10,6 +11,7 @@ module Duse
10
11
  subcommand SecretAdd
11
12
  subcommand SecretGet
12
13
  subcommand SecretList
14
+ subcommand SecretTree
13
15
  subcommand SecretRemove
14
16
  subcommand SecretUpdate
15
17
 
@@ -16,6 +16,7 @@ module Duse
16
16
  on('-s', '--secret [SECRET]', 'The secret to save')
17
17
  on('-g', '--generate-secret', 'Automatically generate the secret')
18
18
  on('-f', '--file [FILE]', 'Read the secret to save from this file')
19
+ on('--folder [FOLDER]', 'The folder to put the secret in')
19
20
 
20
21
  def run
21
22
  self.title ||= terminal.ask 'What do you want to call this secret? '
@@ -23,6 +24,9 @@ module Duse
23
24
  self.secret = SecretGenerator.new.generated_password if generate_secret?
24
25
  self.secret ||= terminal.ask 'Secret to save: '
25
26
  users = who_to_share_with
27
+ if self.folder.nil? && terminal.agree('Put secret in a folder other than the root folder?[y/n] ')
28
+ self.folder = terminal.ask 'Which folder do you want to put the secret in? (provide the id) '
29
+ end
26
30
 
27
31
  user = Duse::User.current
28
32
  ensure_matching_keys_for user
@@ -30,6 +34,7 @@ module Duse
30
34
  secret_hash = Duse::Client::CreateSecret.with(
31
35
  title: self.title,
32
36
  secret_text: self.secret,
37
+ folder_id: self.folder,
33
38
  users: users
34
39
  ).sign_with(private_key).build
35
40
 
@@ -8,9 +8,7 @@ module Duse
8
8
 
9
9
  def run
10
10
  secrets = Duse::Secret.all
11
- secrets.each do |s|
12
- say "#{s.id}: #{s.title}"
13
- end
11
+ secrets.each { |s| say s.to_s }
14
12
  if secrets.empty?
15
13
  say 'You have not yet saved any secrets, ' \
16
14
  "you can do so with \"duse #{SecretAdd.full_command}\"."
@@ -0,0 +1,15 @@
1
+ require 'duse/cli'
2
+ require 'tree_outline'
3
+
4
+ module Duse
5
+ module CLI
6
+ class SecretTree < ApiCommand
7
+ description 'Print all secrets you have access to in a tree'
8
+
9
+ def run
10
+ root_folders = Duse::Folder.all
11
+ say TreeOutline.new(root_folders.first).to_s
12
+ end
13
+ end
14
+ end
15
+ end
@@ -36,7 +36,8 @@ module Duse
36
36
  title = terminal.ask 'What do you want to call this secret? ' if terminal.agree 'Change the title? '
37
37
  secret_text = terminal.ask 'Secret to save: ' if terminal.agree 'Change the secret? '
38
38
  users = who_to_share_with if terminal.agree 'Change accessible users? '
39
- { title: title, secret_text: secret_text, users: users }.delete_if { |k, v| v.nil? }
39
+ folder = terminal.ask 'Which folder do you want to put the secret in? (provide the id) ' if terminal.agree 'Change the folder the secret lies in?[y/n] '
40
+ { title: title, secret_text: secret_text, users: users, folder_id: folder }.delete_if { |k, v| v.nil? }
40
41
  end
41
42
  end
42
43
  end
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'duse/client/entity'
4
+
5
+ module Duse
6
+ module Client
7
+ class Folder < Entity
8
+ FOLDER_SYMBOL = '📂'
9
+
10
+ attributes :id, :name
11
+ has :secrets
12
+ has :subfolders
13
+
14
+ id_field :id
15
+ one :folder
16
+ one :subfolder
17
+ many :folders
18
+ many :subfolders
19
+
20
+ def children
21
+ self.subfolders + self.secrets
22
+ end
23
+
24
+ def id_name
25
+ return "#{FOLDER_SYMBOL} #{self.name}" if self.id.nil?
26
+ "#{FOLDER_SYMBOL} #{self.id}: #{self.name}"
27
+ end
28
+
29
+ def to_s
30
+ "#{FOLDER_SYMBOL} #{self.name}"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  require 'duse/client/entity'
2
4
  require 'duse/encryption'
3
5
  require 'secret_sharing'
@@ -23,6 +25,7 @@ module Duse
23
25
  def build
24
26
  result = {}
25
27
  result[:title] = @values[:title] if @values[:title]
28
+ result[:folder_id] = @values[:folder_id].to_i if @values[:folder_id]
26
29
  if @values[:secret_text]
27
30
  users = @secret.users || @values[:current_users]
28
31
  cipher_text, shares = Encryption.encrypt(@values[:secret_text], users, @private_key)
@@ -53,7 +56,8 @@ module Duse
53
56
  {
54
57
  title: @options[:title],
55
58
  cipher_text: cipher_text,
56
- shares: shares
59
+ shares: shares,
60
+ folder_id: @options[:folder_id]
57
61
  }
58
62
  end
59
63
  end
@@ -66,6 +70,8 @@ module Duse
66
70
  @title = options.fetch(:title)
67
71
  @secret_text = options.fetch(:secret_text)
68
72
  @users = options.fetch(:users)
73
+ @folder_id = options.fetch(:folder_id, nil)
74
+ @folder_id = @folder_id.to_i if !@folder_id.nil?
69
75
  end
70
76
 
71
77
  def sign_with(private_key)
@@ -73,7 +79,8 @@ module Duse
73
79
  title: @title,
74
80
  secret_text: @secret_text,
75
81
  users: @users,
76
- private_key: private_key
82
+ private_key: private_key,
83
+ folder_id: @folder_id
77
84
  )
78
85
  end
79
86
  end
@@ -101,6 +108,10 @@ module Duse
101
108
  end
102
109
  true
103
110
  end
111
+
112
+ def to_s
113
+ "🔐 #{self.id}: #{self.title}"
114
+ end
104
115
  end
105
116
 
106
117
  class Share < Entity
@@ -1,9 +1,16 @@
1
1
  require 'openssl'
2
2
  require 'digest/sha2'
3
3
  require 'base64'
4
+ require 'secret_sharing'
4
5
 
5
6
  module Duse
6
7
  module Encryption
8
+ module Digest
9
+ def digest
10
+ OpenSSL::Digest::SHA256.new
11
+ end
12
+ end
13
+
7
14
  module Encoding
8
15
  def encode(plain_text)
9
16
  Base64.encode64(plain_text).encode('utf-8')
@@ -17,9 +24,11 @@ module Duse
17
24
  module Asymmetric
18
25
  extend self
19
26
  extend Duse::Encryption::Encoding
27
+ extend Duse::Encryption::Digest
28
+ PADDING = OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING
20
29
 
21
30
  def encrypt(private_key, public_key, text)
22
- encrypted = public_key.public_encrypt text.force_encoding('ascii-8bit')
31
+ encrypted = public_key.public_encrypt text.force_encoding('ascii-8bit'), PADDING
23
32
  signature = sign(private_key, encrypted)
24
33
  [encode(encrypted), signature]
25
34
  end
@@ -29,16 +38,12 @@ module Duse
29
38
  end
30
39
 
31
40
  def decrypt(private_key, text)
32
- private_key.private_decrypt(decode(text)).force_encoding('utf-8')
41
+ private_key.private_decrypt(decode(text), PADDING).force_encoding('utf-8')
33
42
  end
34
43
 
35
44
  def verify(public_key, signature, encrypted)
36
45
  public_key.verify digest, decode(signature), decode(encrypted)
37
46
  end
38
-
39
- def digest
40
- OpenSSL::Digest::SHA256.new
41
- end
42
47
  end
43
48
 
44
49
  module Symmetric
@@ -78,7 +83,22 @@ module Duse
78
83
  end
79
84
  end
80
85
 
86
+ module CryptographicHash
87
+ extend self
88
+ extend Duse::Encryption::Encoding
89
+ extend Duse::Encryption::Digest
90
+
91
+ def hmac(key, data)
92
+ encode(OpenSSL::HMAC.digest(digest, key, data))
93
+ end
94
+ end
95
+
81
96
  extend self
97
+ extend Duse::Encryption::Encoding
98
+
99
+ def hmac(key, data)
100
+ Duse::Encryption::CryptographicHash.hmac(key, data)
101
+ end
82
102
 
83
103
  def encrypt(secret_text, users, private_key)
84
104
  key, iv, cipher_text = Encryption::Symmetric.encrypt secret_text
@@ -95,8 +115,12 @@ module Duse
95
115
  raw_shares = SecretSharing.split(symmetric_key, 2, users.length)
96
116
  users.map.with_index do |user, index|
97
117
  share = raw_shares[index]
98
- content, signature = Encryption::Asymmetric.encrypt(private_key, user.public_key, share)
99
- {"user_id" => user.id, "content" => content, "signature" => signature}
118
+ cipher, signature = Encryption::Asymmetric.encrypt(private_key, user.public_key, share)
119
+ {
120
+ "user_id" => user.id,
121
+ "content" => cipher,
122
+ "signature" => signature
123
+ }
100
124
  end
101
125
  end
102
126
 
@@ -1,3 +1,3 @@
1
1
  module Duse
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.8'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  require 'duse/cli/cli_config'
2
2
 
3
- RSpec.describe Duse::CLIConfig do
3
+ RSpec.describe Duse::CLIConfig, :fs => :fake do
4
4
  describe '.load' do
5
5
  context 'config file does not exist' do
6
6
  it 'returns an empty hash' do
@@ -1,4 +1,4 @@
1
- RSpec.describe 'duse account' do
1
+ RSpec.describe 'duse account', :fs => :fake do
2
2
  before :each do
3
3
  FileUtils.mkdir_p Duse::CLIConfig.config_dir
4
4
  open(Duse::CLIConfig.config_file, 'w') do |f|
@@ -1,4 +1,4 @@
1
- describe 'duse config' do
1
+ describe 'duse config', :fs => :fake do
2
2
  context 'false uri provided' do
3
3
  it 'errors with a message' do
4
4
  expect(run_cli('config') { |i| i.puts('test') }.err).to eq(
@@ -1,4 +1,4 @@
1
- describe 'duse login' do
1
+ describe 'duse login', :fs => :fake do
2
2
  before :each do
3
3
  FileUtils.mkdir_p Duse::CLIConfig.config_dir
4
4
  open(Duse::CLIConfig.config_file, 'w') do |f|
@@ -10,7 +10,7 @@ describe 'duse login' do
10
10
  context 'correct credentials' do
11
11
  it 'writes the auth token in the config file' do
12
12
  open(File.join(Duse::CLIConfig.config_dir, 'flower-pot'), 'w') do |f|
13
- f.puts "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmMm3Ovh7gU0rLHK4NiHhWaYRrV9PH6XtHqV0GoiHH7awrjVk\nT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ7FLTWMZNoZ/uh41g4Iv17Wh1I3Fg\nqihdm83cSWvJ81qQCVGBaKeVitSa49zT/MmooBvYFwulaqJjhqFc3862Rl3WowzG\nVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1nng06HIAvMqUcGMebgoju9SuKaR+C\n46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHSI9hTEuPopPSyRqz/EVQfbhi0Lbkd\nDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7AwIDAQABAoIBAQCGSVyLLxRWC/4z\nPc0cfuCyy5xj1g4UEeD7+421OGQTAp39L54vgTzG76SJL/hIsn660b46ZL7BxUd8\nPiK2Mi/C1fU95GUc9hVO/Hq2QS1wcUvrT94XEA1eQCwqN9uy0Nkh54om8owkDkLo\nnRGQ76kOuApQDwNfWsTA8phPeT6JTtr+2K2yc0H4G5G0+py2GDclq56E99SljAqq\nwjFKGazqF0pxJvqLRCR9uVt0FgrRANOLGvxPMNZtnkVBVHmXs1iRD7BUALfESGS1\nHXZxjvD487E2h0Vjkli7rqnu6FZNgQ8Mq5TOfIm5i04LeGCgSTNP9sw7vdZgaYgT\nDPK9BIlZAoGBAMlhenDUOkT1dm28CjGCkygM1kUgDTQDLyBXW/JacotRp3GVZLr2\nV/2rZ3JPxva0cjjs3X4q/CxYsHvqI/ImXbsTBOYIT1/y1fgmXvN6AbiVW5Qne1UD\nneEGqCyB6YfKV2/8CX5Ru01Ay1EYVQDU4APkR1P4H38CuTMeu8SHK/BHAoGBAMI6\nR6TeEIdLprWRmUKU8Iuiwwm0SVxle2trSj6mknsJ93sK7gQkoKNzw0qwZdM6ApKH\nbJo/LiwiZ1Znx1NOyDsKT/ET6CSl59jOBuSUoxqTJ8XvrWlSD8pkbOJ2zWF8WqFR\ncC74bNFgd+n0tftR/7dwkriebITrp5IpF6P2Z9llAoGAAqO3ciEl/l9lRPzw+UMn\n4J+Cc3d/FM5x4K+kceHDnJXeZvu5TUYLUzTa70Gibvtgf+SC5rNziLVE4urnu7XL\nBreyGb3EJJLPQShnmDNiMGQsxh1aXXvlptxqeeLeB7ycNsiL607w8ItH3vE9s/wW\nT5a/ZJdc+lIz0Tq25VWMOuMCgYAejVZZu8izz5WguA94pr8T5/1wGFj13MzGP/FE\n26TtD8tLIpQAONa//2S36fmKeXSQIhdWSBv2O08wC1ESbLEYgG3EyVHZ+fL3aqkw\n6aSieIVoIGSRzaPIPXXXRcLW093ZxFq2OMO9R8R1G9ZIe0STUXTy75C4c+0/E5Gx\nbAA39QKBgDLjtjmG3nJGpQuaftAAjJR+AcA3svSdVug7w5k6D+lxBeM/x4pGP9z4\nkdOrqeD6bv1cctouVVywK/ZQ8dyLczJoGfJIlCvacI1L7fyVUpBp2Lby/uwYMd5w\ngswew+6Xnvtx15SirvYQmDRzA71KBSA4GxpaFwthRIxIwn881m5U\n-----END RSA PRIVATE KEY-----\n"
13
+ f.puts user_private_key.to_s
14
14
  end
15
15
  stub_user_me_get
16
16
  stub_request(:post, "https://example.com/users/token").
@@ -1,4 +1,4 @@
1
- describe 'duse register' do
1
+ describe 'duse register', :fs => :fake do
2
2
  before :each do
3
3
  FileUtils.mkdir_p Duse::CLIConfig.config_dir
4
4
 
@@ -1,4 +1,6 @@
1
- RSpec.describe 'duse secret' do
1
+ # encoding: UTF-8
2
+
3
+ RSpec.describe 'duse secret', :fs => :fake do
2
4
  before :each do
3
5
  FileUtils.mkdir_p Duse::CLIConfig.config_dir
4
6
  open(Duse::CLIConfig.config_file, 'w') do |f|
@@ -7,7 +9,7 @@ RSpec.describe 'duse secret' do
7
9
  f.puts 'token: token'
8
10
  end
9
11
  open(File.join(Duse::CLIConfig.config_dir, 'flower-pot'), 'w') do |f|
10
- f.puts "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmMm3Ovh7gU0rLHK4NiHhWaYRrV9PH6XtHqV0GoiHH7awrjVk\nT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ7FLTWMZNoZ/uh41g4Iv17Wh1I3Fg\nqihdm83cSWvJ81qQCVGBaKeVitSa49zT/MmooBvYFwulaqJjhqFc3862Rl3WowzG\nVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1nng06HIAvMqUcGMebgoju9SuKaR+C\n46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHSI9hTEuPopPSyRqz/EVQfbhi0Lbkd\nDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7AwIDAQABAoIBAQCGSVyLLxRWC/4z\nPc0cfuCyy5xj1g4UEeD7+421OGQTAp39L54vgTzG76SJL/hIsn660b46ZL7BxUd8\nPiK2Mi/C1fU95GUc9hVO/Hq2QS1wcUvrT94XEA1eQCwqN9uy0Nkh54om8owkDkLo\nnRGQ76kOuApQDwNfWsTA8phPeT6JTtr+2K2yc0H4G5G0+py2GDclq56E99SljAqq\nwjFKGazqF0pxJvqLRCR9uVt0FgrRANOLGvxPMNZtnkVBVHmXs1iRD7BUALfESGS1\nHXZxjvD487E2h0Vjkli7rqnu6FZNgQ8Mq5TOfIm5i04LeGCgSTNP9sw7vdZgaYgT\nDPK9BIlZAoGBAMlhenDUOkT1dm28CjGCkygM1kUgDTQDLyBXW/JacotRp3GVZLr2\nV/2rZ3JPxva0cjjs3X4q/CxYsHvqI/ImXbsTBOYIT1/y1fgmXvN6AbiVW5Qne1UD\nneEGqCyB6YfKV2/8CX5Ru01Ay1EYVQDU4APkR1P4H38CuTMeu8SHK/BHAoGBAMI6\nR6TeEIdLprWRmUKU8Iuiwwm0SVxle2trSj6mknsJ93sK7gQkoKNzw0qwZdM6ApKH\nbJo/LiwiZ1Znx1NOyDsKT/ET6CSl59jOBuSUoxqTJ8XvrWlSD8pkbOJ2zWF8WqFR\ncC74bNFgd+n0tftR/7dwkriebITrp5IpF6P2Z9llAoGAAqO3ciEl/l9lRPzw+UMn\n4J+Cc3d/FM5x4K+kceHDnJXeZvu5TUYLUzTa70Gibvtgf+SC5rNziLVE4urnu7XL\nBreyGb3EJJLPQShnmDNiMGQsxh1aXXvlptxqeeLeB7ycNsiL607w8ItH3vE9s/wW\nT5a/ZJdc+lIz0Tq25VWMOuMCgYAejVZZu8izz5WguA94pr8T5/1wGFj13MzGP/FE\n26TtD8tLIpQAONa//2S36fmKeXSQIhdWSBv2O08wC1ESbLEYgG3EyVHZ+fL3aqkw\n6aSieIVoIGSRzaPIPXXXRcLW093ZxFq2OMO9R8R1G9ZIe0STUXTy75C4c+0/E5Gx\nbAA39QKBgDLjtjmG3nJGpQuaftAAjJR+AcA3svSdVug7w5k6D+lxBeM/x4pGP9z4\nkdOrqeD6bv1cctouVVywK/ZQ8dyLczJoGfJIlCvacI1L7fyVUpBp2Lby/uwYMd5w\ngswew+6Xnvtx15SirvYQmDRzA71KBSA4GxpaFwthRIxIwn881m5U\n-----END RSA PRIVATE KEY-----\n"
12
+ f.puts user_private_key.to_s
11
13
  end
12
14
  end
13
15
 
@@ -61,7 +63,7 @@ RSpec.describe 'duse secret' do
61
63
  stub_secret_get
62
64
  stub_user_me_get
63
65
  stub_server_user_get
64
- stub_user_get1
66
+ stub_user_get2
65
67
  stub_user_get2
66
68
 
67
69
  run_cli('secret', 'get') { |i| i.puts('1') }
@@ -74,12 +76,24 @@ RSpec.describe 'duse secret' do
74
76
  end
75
77
  end
76
78
 
79
+ describe 'tree' do
80
+ xit 'prints the secrets in folder/secrets tree' do
81
+ stub_get_folders
82
+
83
+ expect(run_cli('secret', 'tree').out).to eq(
84
+ "1: test\n"
85
+ )
86
+ end
87
+ end
88
+
77
89
  describe 'list' do
78
- it 'lists secrets' do
90
+ it 'lists secrets as id:secret pairs' do
79
91
  stub_get_secrets
80
92
 
81
- expect(run_cli('secret', 'list').out).to eq(
82
- "1: test\n"
93
+ run_cli('secret', 'list')
94
+ output = last_run.out
95
+ expect(output).to eq(
96
+ "🔐 1: test\n"
83
97
  )
84
98
  end
85
99
  end
@@ -106,6 +120,7 @@ RSpec.describe 'duse secret' do
106
120
  i.puts 'test'
107
121
  i.puts 'test'
108
122
  i.puts 'n'
123
+ i.puts 'n'
109
124
  end.success?).to be true
110
125
  end
111
126
  end
@@ -123,6 +138,7 @@ RSpec.describe 'duse secret' do
123
138
  i.puts 'test'
124
139
  i.puts 'y'
125
140
  i.puts '1'
141
+ i.puts 'n'
126
142
  end.success?).to be true
127
143
 
128
144
  expect(last_run.out).to match(
@@ -145,6 +161,7 @@ RSpec.describe 'duse secret' do
145
161
  i.puts 'Y'
146
162
  i.puts '3'
147
163
  i.puts '1'
164
+ i.puts 'n'
148
165
  end.success?).to be true
149
166
  end
150
167
  end
@@ -25,12 +25,11 @@ RSpec.describe Duse::Client::Secret do
25
25
  context 'secret exists' do
26
26
  it 'loads a single secret with shares' do
27
27
  stub_secret_get
28
- private_key = OpenSSL::PKey::RSA.new "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmMm3Ovh7gU0rLHK4NiHhWaYRrV9PH6XtHqV0GoiHH7awrjVk\nT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ7FLTWMZNoZ/uh41g4Iv17Wh1I3Fg\nqihdm83cSWvJ81qQCVGBaKeVitSa49zT/MmooBvYFwulaqJjhqFc3862Rl3WowzG\nVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1nng06HIAvMqUcGMebgoju9SuKaR+C\n46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHSI9hTEuPopPSyRqz/EVQfbhi0Lbkd\nDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7AwIDAQABAoIBAQCGSVyLLxRWC/4z\nPc0cfuCyy5xj1g4UEeD7+421OGQTAp39L54vgTzG76SJL/hIsn660b46ZL7BxUd8\nPiK2Mi/C1fU95GUc9hVO/Hq2QS1wcUvrT94XEA1eQCwqN9uy0Nkh54om8owkDkLo\nnRGQ76kOuApQDwNfWsTA8phPeT6JTtr+2K2yc0H4G5G0+py2GDclq56E99SljAqq\nwjFKGazqF0pxJvqLRCR9uVt0FgrRANOLGvxPMNZtnkVBVHmXs1iRD7BUALfESGS1\nHXZxjvD487E2h0Vjkli7rqnu6FZNgQ8Mq5TOfIm5i04LeGCgSTNP9sw7vdZgaYgT\nDPK9BIlZAoGBAMlhenDUOkT1dm28CjGCkygM1kUgDTQDLyBXW/JacotRp3GVZLr2\nV/2rZ3JPxva0cjjs3X4q/CxYsHvqI/ImXbsTBOYIT1/y1fgmXvN6AbiVW5Qne1UD\nneEGqCyB6YfKV2/8CX5Ru01Ay1EYVQDU4APkR1P4H38CuTMeu8SHK/BHAoGBAMI6\nR6TeEIdLprWRmUKU8Iuiwwm0SVxle2trSj6mknsJ93sK7gQkoKNzw0qwZdM6ApKH\nbJo/LiwiZ1Znx1NOyDsKT/ET6CSl59jOBuSUoxqTJ8XvrWlSD8pkbOJ2zWF8WqFR\ncC74bNFgd+n0tftR/7dwkriebITrp5IpF6P2Z9llAoGAAqO3ciEl/l9lRPzw+UMn\n4J+Cc3d/FM5x4K+kceHDnJXeZvu5TUYLUzTa70Gibvtgf+SC5rNziLVE4urnu7XL\nBreyGb3EJJLPQShnmDNiMGQsxh1aXXvlptxqeeLeB7ycNsiL607w8ItH3vE9s/wW\nT5a/ZJdc+lIz0Tq25VWMOuMCgYAejVZZu8izz5WguA94pr8T5/1wGFj13MzGP/FE\n26TtD8tLIpQAONa//2S36fmKeXSQIhdWSBv2O08wC1ESbLEYgG3EyVHZ+fL3aqkw\n6aSieIVoIGSRzaPIPXXXRcLW093ZxFq2OMO9R8R1G9ZIe0STUXTy75C4c+0/E5Gx\nbAA39QKBgDLjtjmG3nJGpQuaftAAjJR+AcA3svSdVug7w5k6D+lxBeM/x4pGP9z4\nkdOrqeD6bv1cctouVVywK/ZQ8dyLczJoGfJIlCvacI1L7fyVUpBp2Lby/uwYMd5w\ngswew+6Xnvtx15SirvYQmDRzA71KBSA4GxpaFwthRIxIwn881m5U\n-----END RSA PRIVATE KEY-----\n"
29
28
 
30
29
  secret = Duse::Secret.find 1
31
30
 
32
31
  expect(secret.title).to eq 'test'
33
- expect(secret.decrypt(private_key)).to eq 'test'
32
+ expect(secret.decrypt(user_private_key)).to eq 'test'
34
33
  end
35
34
  end
36
35
 
@@ -63,45 +62,38 @@ RSpec.describe Duse::Client::Secret do
63
62
  describe '.create' do
64
63
  it 'builds a secret' do
65
64
  stub_create_secret
66
- current_user_private_key = OpenSSL::PKey::RSA.new "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmMm3Ovh7gU0rLHK4NiHhWaYRrV9PH6XtHqV0GoiHH7awrjVk\nT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ7FLTWMZNoZ/uh41g4Iv17Wh1I3Fg\nqihdm83cSWvJ81qQCVGBaKeVitSa49zT/MmooBvYFwulaqJjhqFc3862Rl3WowzG\nVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1nng06HIAvMqUcGMebgoju9SuKaR+C\n46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHSI9hTEuPopPSyRqz/EVQfbhi0Lbkd\nDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7AwIDAQABAoIBAQCGSVyLLxRWC/4z\nPc0cfuCyy5xj1g4UEeD7+421OGQTAp39L54vgTzG76SJL/hIsn660b46ZL7BxUd8\nPiK2Mi/C1fU95GUc9hVO/Hq2QS1wcUvrT94XEA1eQCwqN9uy0Nkh54om8owkDkLo\nnRGQ76kOuApQDwNfWsTA8phPeT6JTtr+2K2yc0H4G5G0+py2GDclq56E99SljAqq\nwjFKGazqF0pxJvqLRCR9uVt0FgrRANOLGvxPMNZtnkVBVHmXs1iRD7BUALfESGS1\nHXZxjvD487E2h0Vjkli7rqnu6FZNgQ8Mq5TOfIm5i04LeGCgSTNP9sw7vdZgaYgT\nDPK9BIlZAoGBAMlhenDUOkT1dm28CjGCkygM1kUgDTQDLyBXW/JacotRp3GVZLr2\nV/2rZ3JPxva0cjjs3X4q/CxYsHvqI/ImXbsTBOYIT1/y1fgmXvN6AbiVW5Qne1UD\nneEGqCyB6YfKV2/8CX5Ru01Ay1EYVQDU4APkR1P4H38CuTMeu8SHK/BHAoGBAMI6\nR6TeEIdLprWRmUKU8Iuiwwm0SVxle2trSj6mknsJ93sK7gQkoKNzw0qwZdM6ApKH\nbJo/LiwiZ1Znx1NOyDsKT/ET6CSl59jOBuSUoxqTJ8XvrWlSD8pkbOJ2zWF8WqFR\ncC74bNFgd+n0tftR/7dwkriebITrp5IpF6P2Z9llAoGAAqO3ciEl/l9lRPzw+UMn\n4J+Cc3d/FM5x4K+kceHDnJXeZvu5TUYLUzTa70Gibvtgf+SC5rNziLVE4urnu7XL\nBreyGb3EJJLPQShnmDNiMGQsxh1aXXvlptxqeeLeB7ycNsiL607w8ItH3vE9s/wW\nT5a/ZJdc+lIz0Tq25VWMOuMCgYAejVZZu8izz5WguA94pr8T5/1wGFj13MzGP/FE\n26TtD8tLIpQAONa//2S36fmKeXSQIhdWSBv2O08wC1ESbLEYgG3EyVHZ+fL3aqkw\n6aSieIVoIGSRzaPIPXXXRcLW093ZxFq2OMO9R8R1G9ZIe0STUXTy75C4c+0/E5Gx\nbAA39QKBgDLjtjmG3nJGpQuaftAAjJR+AcA3svSdVug7w5k6D+lxBeM/x4pGP9z4\nkdOrqeD6bv1cctouVVywK/ZQ8dyLczJoGfJIlCvacI1L7fyVUpBp2Lby/uwYMd5w\ngswew+6Xnvtx15SirvYQmDRzA71KBSA4GxpaFwthRIxIwn881m5U\n-----END RSA PRIVATE KEY-----\n"
67
- current_user_public_key = OpenSSL::PKey::RSA.new "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmMm3Ovh7gU0rLHK4NiHh\nWaYRrV9PH6XtHqV0GoiHH7awrjVkT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ\n7FLTWMZNoZ/uh41g4Iv17Wh1I3Fgqihdm83cSWvJ81qQCVGBaKeVitSa49zT/Mmo\noBvYFwulaqJjhqFc3862Rl3WowzGVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1n\nng06HIAvMqUcGMebgoju9SuKaR+C46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHS\nI9hTEuPopPSyRqz/EVQfbhi0LbkdDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7\nAwIDAQAB\n-----END PUBLIC KEY-----\n"
68
- server_user_public_key = OpenSSL::PKey::RSA.new "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvyvyAf7lnVx9eQcAS7JL\nYRHrqJJe51rAdanaUiiy8eek2Iyh6JG551EK7x4n9/Y7r0fW2sNmy+Bp3FpL8E/p\ncxutggTWCnUQUvXmEEm5qZ1KOIIlEQNp5glToAenJ7pxotJsTMlVw4tizsKScenc\n8w+02wpcmWuzWKjoY/G5KV33UDz/LxVo1RJdJp94JiL/OinIl+uk+Vf7VZj/E8g/\n7DyXIuiBosVpj9E9T4kpxs3/7RmUfDzUisVq0UvgflRjvP1V+1KdpNnjVB+H08mb\nSVO6yf2YOcrPDRa3pgz7PIr225QJ+HmVjPTg5VAy7rUxhCK+q+HNd2oz35zA70SO\npQIDAQAB\n-----END PUBLIC KEY-----\n"
69
- current_user = OpenStruct.new id: 1, public_key: current_user_public_key
70
- server_user = OpenStruct.new id: 2, public_key: server_user_public_key
65
+ current_user = OpenStruct.new id: 1, public_key: user_public_key
66
+ server_user = OpenStruct.new id: 2, public_key: server_public_key
71
67
 
72
68
  secret_json = Duse::Client::CreateSecret.with(
73
69
  title: 'secret title',
74
70
  secret_text: 'test',
75
71
  users: [current_user, server_user]
76
- ).sign_with(current_user_private_key).build
72
+ ).sign_with(user_private_key).build
77
73
  secret = Duse::Secret.create secret_json
78
74
 
79
75
  expect(secret.title).to eq 'test'
80
- expect(secret.decrypt(current_user_private_key)).to eq 'test'
76
+ expect(secret.decrypt(user_private_key)).to eq 'test'
81
77
  end
82
78
  end
83
79
 
84
80
  describe 'creation process' do
85
81
  context 'own and server user' do
86
82
  def test_working_encryption_and_decryption_for(plaintext)
87
- current_user_private_key = OpenSSL::PKey::RSA.new "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmMm3Ovh7gU0rLHK4NiHhWaYRrV9PH6XtHqV0GoiHH7awrjVk\nT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ7FLTWMZNoZ/uh41g4Iv17Wh1I3Fg\nqihdm83cSWvJ81qQCVGBaKeVitSa49zT/MmooBvYFwulaqJjhqFc3862Rl3WowzG\nVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1nng06HIAvMqUcGMebgoju9SuKaR+C\n46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHSI9hTEuPopPSyRqz/EVQfbhi0Lbkd\nDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7AwIDAQABAoIBAQCGSVyLLxRWC/4z\nPc0cfuCyy5xj1g4UEeD7+421OGQTAp39L54vgTzG76SJL/hIsn660b46ZL7BxUd8\nPiK2Mi/C1fU95GUc9hVO/Hq2QS1wcUvrT94XEA1eQCwqN9uy0Nkh54om8owkDkLo\nnRGQ76kOuApQDwNfWsTA8phPeT6JTtr+2K2yc0H4G5G0+py2GDclq56E99SljAqq\nwjFKGazqF0pxJvqLRCR9uVt0FgrRANOLGvxPMNZtnkVBVHmXs1iRD7BUALfESGS1\nHXZxjvD487E2h0Vjkli7rqnu6FZNgQ8Mq5TOfIm5i04LeGCgSTNP9sw7vdZgaYgT\nDPK9BIlZAoGBAMlhenDUOkT1dm28CjGCkygM1kUgDTQDLyBXW/JacotRp3GVZLr2\nV/2rZ3JPxva0cjjs3X4q/CxYsHvqI/ImXbsTBOYIT1/y1fgmXvN6AbiVW5Qne1UD\nneEGqCyB6YfKV2/8CX5Ru01Ay1EYVQDU4APkR1P4H38CuTMeu8SHK/BHAoGBAMI6\nR6TeEIdLprWRmUKU8Iuiwwm0SVxle2trSj6mknsJ93sK7gQkoKNzw0qwZdM6ApKH\nbJo/LiwiZ1Znx1NOyDsKT/ET6CSl59jOBuSUoxqTJ8XvrWlSD8pkbOJ2zWF8WqFR\ncC74bNFgd+n0tftR/7dwkriebITrp5IpF6P2Z9llAoGAAqO3ciEl/l9lRPzw+UMn\n4J+Cc3d/FM5x4K+kceHDnJXeZvu5TUYLUzTa70Gibvtgf+SC5rNziLVE4urnu7XL\nBreyGb3EJJLPQShnmDNiMGQsxh1aXXvlptxqeeLeB7ycNsiL607w8ItH3vE9s/wW\nT5a/ZJdc+lIz0Tq25VWMOuMCgYAejVZZu8izz5WguA94pr8T5/1wGFj13MzGP/FE\n26TtD8tLIpQAONa//2S36fmKeXSQIhdWSBv2O08wC1ESbLEYgG3EyVHZ+fL3aqkw\n6aSieIVoIGSRzaPIPXXXRcLW093ZxFq2OMO9R8R1G9ZIe0STUXTy75C4c+0/E5Gx\nbAA39QKBgDLjtjmG3nJGpQuaftAAjJR+AcA3svSdVug7w5k6D+lxBeM/x4pGP9z4\nkdOrqeD6bv1cctouVVywK/ZQ8dyLczJoGfJIlCvacI1L7fyVUpBp2Lby/uwYMd5w\ngswew+6Xnvtx15SirvYQmDRzA71KBSA4GxpaFwthRIxIwn881m5U\n-----END RSA PRIVATE KEY-----\n"
88
- current_user_public_key = OpenSSL::PKey::RSA.new "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmMm3Ovh7gU0rLHK4NiHh\nWaYRrV9PH6XtHqV0GoiHH7awrjVkT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ\n7FLTWMZNoZ/uh41g4Iv17Wh1I3Fgqihdm83cSWvJ81qQCVGBaKeVitSa49zT/Mmo\noBvYFwulaqJjhqFc3862Rl3WowzGVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1n\nng06HIAvMqUcGMebgoju9SuKaR+C46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHS\nI9hTEuPopPSyRqz/EVQfbhi0LbkdDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7\nAwIDAQAB\n-----END PUBLIC KEY-----\n"
89
- server_user_private_key = OpenSSL::PKey::RSA.new "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAvyvyAf7lnVx9eQcAS7JLYRHrqJJe51rAdanaUiiy8eek2Iyh\n6JG551EK7x4n9/Y7r0fW2sNmy+Bp3FpL8E/pcxutggTWCnUQUvXmEEm5qZ1KOIIl\nEQNp5glToAenJ7pxotJsTMlVw4tizsKScenc8w+02wpcmWuzWKjoY/G5KV33UDz/\nLxVo1RJdJp94JiL/OinIl+uk+Vf7VZj/E8g/7DyXIuiBosVpj9E9T4kpxs3/7RmU\nfDzUisVq0UvgflRjvP1V+1KdpNnjVB+H08mbSVO6yf2YOcrPDRa3pgz7PIr225QJ\n+HmVjPTg5VAy7rUxhCK+q+HNd2oz35zA70SOpQIDAQABAoIBAQCHXFJrX1St64Nc\nYryu3HvLK6k1Hw7bucJ0jePsMK0j4+Uw/8LUrfp380ZOsYeTZ2IzZiaXl6v9x9St\nFbKXYb3mpz5fxZTYqrL4Suyvs8QmeRzIjj44obYmD4yKz2BoHPfBVkUgyZ5Uayl3\nRQX0aqbr478nKVsPttayfEawHcQBqTHPE9dfavuT14/64iqkrIya4ejFVXd1vYG2\nx+oKedPAnD3jr9foEHTqj1D4AeORwonbxFllh3K91IcabV3zdIZH0ICvYaaryceU\n2npp1H0mqETMZ97o3uMo8S5AEK7TsyB26WlD1IUSfwaP3apkog2WMNvgU4c2OD/q\nX8l3mA2BAoGBAOHGaZtBXQUSUD95eQAG/03F1Non21dD+aUtMbDn1Li6aOD+C+a4\ncJVZ+D2nMMIoQz3nEBIVoEdK4prugQXZJ87pvWwpZ/afRmTNSYWHnJmmg5/rvrZ5\nuvR17DwmS5ucTVOWcdryoG0O5KZqyAnpshLecr5PALY+cfG+fjo6KxNpAoGBANjD\noeFiSZ5a9aS8QR4pHkHz4zjDh/JglN4F7QFSLBLdnn54HHguq8oyg6VXQVMv6IA6\nnFv4wcypyjO+wRktwW+pklpoIuPaTNbHykBTjWD+Ew82iEIzh2m9j43UdGM+Kfmh\nGUSCYorwZG41v2GyepnCDWC5H3RslmxZ6+e9XcXdAoGALz3GAS93GEWRtwZi1Cei\nqhJYDGHEmojlprNDL4IC17hhk5p0wQ0cuZN+xt/B6w5jq4M6sJ4H0IMR0VtQcfnT\nQ49TDFvJnigLobH2zVLn6JqX9hFs8V+dR+OYz6kvrtrQr0nOfwK/oLI6E7xKKRDW\nKu6S0dFUE84TJ4M1hFeBhekCgYEAnYX9vBZ7PXMIlECiadKjxHYCKBwgTUlWpcpU\no+MdWFBpf6q1tbjk6rmu5Zb1SAjGw3jUbBnobFzvLo9vMGcJ7aWjT8PhpwfbUzI5\njmmpklTRcPrGJqXfwD4bdoxwUDa6tkgWXq0KA8ISmezBObREWDynECU38JmA7xih\n0PTSkpkCgYBUUASKsz2ThzQiAU+Ivu2Y/QON78N0ZyQ/0kDhxZ8AUnbtGZAOq5pV\nRMj053t5oJMr2eWkMZ5aBYmjo0Uy4vrRCV6SXrlAs3YsN1mh1P+xGRRmX99xwalJ\n6dQaTBdtQ33MhY0+17EXr6WUGRZHIcFM6uGa32MKSmeqkATuV7eyzg==\n-----END RSA PRIVATE KEY-----\n"
90
- server_user_public_key = OpenSSL::PKey::RSA.new "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvyvyAf7lnVx9eQcAS7JL\nYRHrqJJe51rAdanaUiiy8eek2Iyh6JG551EK7x4n9/Y7r0fW2sNmy+Bp3FpL8E/p\ncxutggTWCnUQUvXmEEm5qZ1KOIIlEQNp5glToAenJ7pxotJsTMlVw4tizsKScenc\n8w+02wpcmWuzWKjoY/G5KV33UDz/LxVo1RJdJp94JiL/OinIl+uk+Vf7VZj/E8g/\n7DyXIuiBosVpj9E9T4kpxs3/7RmUfDzUisVq0UvgflRjvP1V+1KdpNnjVB+H08mb\nSVO6yf2YOcrPDRa3pgz7PIr225QJ+HmVjPTg5VAy7rUxhCK+q+HNd2oz35zA70SO\npQIDAQAB\n-----END PUBLIC KEY-----\n"
91
- current_user = OpenStruct.new id: 1, public_key: current_user_public_key
92
- server_user = OpenStruct.new id: 2, public_key: server_user_public_key
83
+ current_user = OpenStruct.new id: 1, public_key: user_public_key
84
+ server_user = OpenStruct.new id: 2, public_key: server_public_key
93
85
  secret = Duse::Client::CreateSecret.with(
94
86
  title: 'test',
95
87
  secret_text: plaintext,
96
88
  users: [current_user, server_user]
97
- ).sign_with(current_user_private_key).build
89
+ ).sign_with(user_private_key).build
98
90
 
99
- shares = secret[:shares].map { |s| Duse::Client::Share.new(s) }
100
- server_share = Duse::Encryption::Asymmetric.decrypt(server_user_private_key, shares[1].content)
101
- shares[1].content, _ = Duse::Encryption::Asymmetric.encrypt(current_user_private_key, current_user_public_key, server_share)
91
+ server_share = Duse::Encryption::Asymmetric.decrypt(server_private_key, secret[:shares][1]['content'])
92
+ secret[:shares][1]['content'], secret[:shares][1]['signature'] = Duse::Encryption::Asymmetric.encrypt(user_private_key, user_public_key, server_share)
102
93
 
94
+ shares = secret[:shares].map { |s| Duse::Client::Share.new(s) }
103
95
  secret = Duse::Client::Secret.new shares: shares, cipher_text: secret[:cipher_text]
104
- decrypted_secret = secret.decrypt(current_user_private_key)
96
+ decrypted_secret = secret.decrypt(user_private_key)
105
97
 
106
98
  expect(decrypted_secret).to eq plaintext
107
99
  end
@@ -111,8 +103,8 @@ RSpec.describe Duse::Client::Secret do
111
103
  test_working_encryption_and_decryption_for(secret_text)
112
104
  end
113
105
 
114
- it 'can hable 4096 bit rsa keys' do
115
- secret_text = "-----BEGIN RSA PRIVATE KEY-----\nMIICWgIBAAKBgQCftZvHkB6uKWVDvrIzmy2p496Hv9PD/hhRk+DSXcE/CPtRmvYZ\nzbWbbBup9hkvhyH/P1O5EF8KSZm4Cdnz6p37idTeNdlaH9cRFV2wc2A/hbg2kaIS\nxrDxUqRbywBE9NOBSjXu2wRpy0TMo85eM2A0E2ET2XM6tZcuwFULX6bl8QIDAQAB\nAoGAEJwyt26lwjdL8N/EaNmaxjCM1FF/FMM4hEN8/mQB1Sx59uLG9agPWzrDJcoS\nlH7ZalKLwpORTuCYvCtKH7Qm+fgnjKl/qyn6/cDmtk6VtJvPjQGi3oh2eRIMcwZv\nva+NQLF11bm0kVtZG5viIKlb1snHzkpPjFAOPBqQj2FNdgECQQDQdHWC5XYww2RQ\n/FpRBacJPIxb8PAwb7+EjqJSaruGO9CtLiDiCzlmidGP0Q++zwjAxksSqP4qkr6k\npKvDqkydAkEAxCLuq0c+6gnE9X1PUy4Bl/hUOxrk3ZQRCMUCE4XB8mNmJTLNY43O\ncY7Z1sdaCu7pAiGxQqojUYgwFACGmbOcZQJAZAvg8mfq59B/bxcOyeAqoRY8T0w+\nGyEnDBng8iljwzMmHlgLVDIK5Jm0yI+QPQXkr5D8KwKMqiYv9ZlLDufHSQJAJs9i\nurGWWWkleA4brDHmTtPsluVzdATgegPBrWtCPVw90g6DZbehqgbCRCWeQ5uSr8FK\n+g4AfxmbqdmQyMkpoQI/HvHjjPB9a/2qkpyjeiJIx2gmCmhBke9V/b3XFGBy3ci7\nLZRZUZLlAdJORX177Ief6MWqgXldlcP1N7mzWskE\n-----END RSA PRIVATE KEY-----\n"
106
+ it 'can hanle 4096 bit rsa keys' do
107
+ secret_text = OpenSSL::PKey::RSA.generate(4096).to_s
116
108
  test_working_encryption_and_decryption_for(secret_text)
117
109
  end
118
110
 
@@ -127,24 +119,20 @@ RSpec.describe Duse::Client::Secret do
127
119
  context 'changin users' do
128
120
  it 'leaves the cipher text unchanged and generates new shares' do
129
121
  stub_secret_get
130
- current_user_private_key = OpenSSL::PKey::RSA.new "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmMm3Ovh7gU0rLHK4NiHhWaYRrV9PH6XtHqV0GoiHH7awrjVk\nT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ7FLTWMZNoZ/uh41g4Iv17Wh1I3Fg\nqihdm83cSWvJ81qQCVGBaKeVitSa49zT/MmooBvYFwulaqJjhqFc3862Rl3WowzG\nVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1nng06HIAvMqUcGMebgoju9SuKaR+C\n46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHSI9hTEuPopPSyRqz/EVQfbhi0Lbkd\nDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7AwIDAQABAoIBAQCGSVyLLxRWC/4z\nPc0cfuCyy5xj1g4UEeD7+421OGQTAp39L54vgTzG76SJL/hIsn660b46ZL7BxUd8\nPiK2Mi/C1fU95GUc9hVO/Hq2QS1wcUvrT94XEA1eQCwqN9uy0Nkh54om8owkDkLo\nnRGQ76kOuApQDwNfWsTA8phPeT6JTtr+2K2yc0H4G5G0+py2GDclq56E99SljAqq\nwjFKGazqF0pxJvqLRCR9uVt0FgrRANOLGvxPMNZtnkVBVHmXs1iRD7BUALfESGS1\nHXZxjvD487E2h0Vjkli7rqnu6FZNgQ8Mq5TOfIm5i04LeGCgSTNP9sw7vdZgaYgT\nDPK9BIlZAoGBAMlhenDUOkT1dm28CjGCkygM1kUgDTQDLyBXW/JacotRp3GVZLr2\nV/2rZ3JPxva0cjjs3X4q/CxYsHvqI/ImXbsTBOYIT1/y1fgmXvN6AbiVW5Qne1UD\nneEGqCyB6YfKV2/8CX5Ru01Ay1EYVQDU4APkR1P4H38CuTMeu8SHK/BHAoGBAMI6\nR6TeEIdLprWRmUKU8Iuiwwm0SVxle2trSj6mknsJ93sK7gQkoKNzw0qwZdM6ApKH\nbJo/LiwiZ1Znx1NOyDsKT/ET6CSl59jOBuSUoxqTJ8XvrWlSD8pkbOJ2zWF8WqFR\ncC74bNFgd+n0tftR/7dwkriebITrp5IpF6P2Z9llAoGAAqO3ciEl/l9lRPzw+UMn\n4J+Cc3d/FM5x4K+kceHDnJXeZvu5TUYLUzTa70Gibvtgf+SC5rNziLVE4urnu7XL\nBreyGb3EJJLPQShnmDNiMGQsxh1aXXvlptxqeeLeB7ycNsiL607w8ItH3vE9s/wW\nT5a/ZJdc+lIz0Tq25VWMOuMCgYAejVZZu8izz5WguA94pr8T5/1wGFj13MzGP/FE\n26TtD8tLIpQAONa//2S36fmKeXSQIhdWSBv2O08wC1ESbLEYgG3EyVHZ+fL3aqkw\n6aSieIVoIGSRzaPIPXXXRcLW093ZxFq2OMO9R8R1G9ZIe0STUXTy75C4c+0/E5Gx\nbAA39QKBgDLjtjmG3nJGpQuaftAAjJR+AcA3svSdVug7w5k6D+lxBeM/x4pGP9z4\nkdOrqeD6bv1cctouVVywK/ZQ8dyLczJoGfJIlCvacI1L7fyVUpBp2Lby/uwYMd5w\ngswew+6Xnvtx15SirvYQmDRzA71KBSA4GxpaFwthRIxIwn881m5U\n-----END RSA PRIVATE KEY-----\n"
131
- current_user_public_key = OpenSSL::PKey::RSA.new "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmMm3Ovh7gU0rLHK4NiHh\nWaYRrV9PH6XtHqV0GoiHH7awrjVkT1aZiS+nlBxckfuvuQjRXakVCZh18UdQadVQ\n7FLTWMZNoZ/uh41g4Iv17Wh1I3Fgqihdm83cSWvJ81qQCVGBaKeVitSa49zT/Mmo\noBvYFwulaqJjhqFc3862Rl3WowzGVqGf+OiYhFrBbnIqXijDmVKsbqkG5AILGo1n\nng06HIAvMqUcGMebgoju9SuKaR+C46KT0K5sPpNw/tNcDEZqZAd25QjAroGnpRHS\nI9hTEuPopPSyRqz/EVQfbhi0LbkdDW9S5ECw7GfFPFpRp2239fjl/9ybL6TkeZL7\nAwIDAQAB\n-----END PUBLIC KEY-----\n"
132
- server_user_private_key = OpenSSL::PKey::RSA.new "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAvyvyAf7lnVx9eQcAS7JLYRHrqJJe51rAdanaUiiy8eek2Iyh\n6JG551EK7x4n9/Y7r0fW2sNmy+Bp3FpL8E/pcxutggTWCnUQUvXmEEm5qZ1KOIIl\nEQNp5glToAenJ7pxotJsTMlVw4tizsKScenc8w+02wpcmWuzWKjoY/G5KV33UDz/\nLxVo1RJdJp94JiL/OinIl+uk+Vf7VZj/E8g/7DyXIuiBosVpj9E9T4kpxs3/7RmU\nfDzUisVq0UvgflRjvP1V+1KdpNnjVB+H08mbSVO6yf2YOcrPDRa3pgz7PIr225QJ\n+HmVjPTg5VAy7rUxhCK+q+HNd2oz35zA70SOpQIDAQABAoIBAQCHXFJrX1St64Nc\nYryu3HvLK6k1Hw7bucJ0jePsMK0j4+Uw/8LUrfp380ZOsYeTZ2IzZiaXl6v9x9St\nFbKXYb3mpz5fxZTYqrL4Suyvs8QmeRzIjj44obYmD4yKz2BoHPfBVkUgyZ5Uayl3\nRQX0aqbr478nKVsPttayfEawHcQBqTHPE9dfavuT14/64iqkrIya4ejFVXd1vYG2\nx+oKedPAnD3jr9foEHTqj1D4AeORwonbxFllh3K91IcabV3zdIZH0ICvYaaryceU\n2npp1H0mqETMZ97o3uMo8S5AEK7TsyB26WlD1IUSfwaP3apkog2WMNvgU4c2OD/q\nX8l3mA2BAoGBAOHGaZtBXQUSUD95eQAG/03F1Non21dD+aUtMbDn1Li6aOD+C+a4\ncJVZ+D2nMMIoQz3nEBIVoEdK4prugQXZJ87pvWwpZ/afRmTNSYWHnJmmg5/rvrZ5\nuvR17DwmS5ucTVOWcdryoG0O5KZqyAnpshLecr5PALY+cfG+fjo6KxNpAoGBANjD\noeFiSZ5a9aS8QR4pHkHz4zjDh/JglN4F7QFSLBLdnn54HHguq8oyg6VXQVMv6IA6\nnFv4wcypyjO+wRktwW+pklpoIuPaTNbHykBTjWD+Ew82iEIzh2m9j43UdGM+Kfmh\nGUSCYorwZG41v2GyepnCDWC5H3RslmxZ6+e9XcXdAoGALz3GAS93GEWRtwZi1Cei\nqhJYDGHEmojlprNDL4IC17hhk5p0wQ0cuZN+xt/B6w5jq4M6sJ4H0IMR0VtQcfnT\nQ49TDFvJnigLobH2zVLn6JqX9hFs8V+dR+OYz6kvrtrQr0nOfwK/oLI6E7xKKRDW\nKu6S0dFUE84TJ4M1hFeBhekCgYEAnYX9vBZ7PXMIlECiadKjxHYCKBwgTUlWpcpU\no+MdWFBpf6q1tbjk6rmu5Zb1SAjGw3jUbBnobFzvLo9vMGcJ7aWjT8PhpwfbUzI5\njmmpklTRcPrGJqXfwD4bdoxwUDa6tkgWXq0KA8ISmezBObREWDynECU38JmA7xih\n0PTSkpkCgYBUUASKsz2ThzQiAU+Ivu2Y/QON78N0ZyQ/0kDhxZ8AUnbtGZAOq5pV\nRMj053t5oJMr2eWkMZ5aBYmjo0Uy4vrRCV6SXrlAs3YsN1mh1P+xGRRmX99xwalJ\n6dQaTBdtQ33MhY0+17EXr6WUGRZHIcFM6uGa32MKSmeqkATuV7eyzg==\n-----END RSA PRIVATE KEY-----\n"
133
- server_user_public_key = OpenSSL::PKey::RSA.new "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvyvyAf7lnVx9eQcAS7JL\nYRHrqJJe51rAdanaUiiy8eek2Iyh6JG551EK7x4n9/Y7r0fW2sNmy+Bp3FpL8E/p\ncxutggTWCnUQUvXmEEm5qZ1KOIIlEQNp5glToAenJ7pxotJsTMlVw4tizsKScenc\n8w+02wpcmWuzWKjoY/G5KV33UDz/LxVo1RJdJp94JiL/OinIl+uk+Vf7VZj/E8g/\n7DyXIuiBosVpj9E9T4kpxs3/7RmUfDzUisVq0UvgflRjvP1V+1KdpNnjVB+H08mb\nSVO6yf2YOcrPDRa3pgz7PIr225QJ+HmVjPTg5VAy7rUxhCK+q+HNd2oz35zA70SO\npQIDAQAB\n-----END PUBLIC KEY-----\n"
134
- current_user = OpenStruct.new id: 1, public_key: current_user_public_key
135
- server_user = OpenStruct.new id: 2, public_key: server_user_public_key
122
+ current_user = OpenStruct.new id: 1, public_key: user_public_key
123
+ server_user = OpenStruct.new id: 2, public_key: server_public_key
136
124
  secret = Duse::Secret.find(1)
137
125
  secret_hash = Duse::Client::UpdateSecret.values(
138
126
  secret,
139
127
  { users: [current_user, server_user] }
140
- ).encrypt_with(current_user_private_key).build
128
+ ).encrypt_with(user_private_key).build
141
129
 
142
130
  shares = secret_hash[:shares].map { |s| Duse::Client::Share.new(s) }
143
- server_share = Duse::Encryption::Asymmetric.decrypt(server_user_private_key, shares[1].content)
144
- shares[1].content, _ = Duse::Encryption::Asymmetric.encrypt(current_user_private_key, current_user_public_key, server_share)
131
+ server_share = Duse::Encryption::Asymmetric.decrypt(server_private_key, shares[1].content)
132
+ shares[1].content, shares[1].signature = Duse::Encryption::Asymmetric.encrypt(user_private_key, user_public_key, server_share)
145
133
 
146
134
  new_secret = Duse::Client::Secret.new shares: shares, cipher_text: secret.cipher_text
147
- decrypted_secret = new_secret.decrypt(current_user_private_key)
135
+ decrypted_secret = new_secret.decrypt(user_private_key)
148
136
 
149
137
  expect(decrypted_secret).to eq 'test'
150
138
  expect(new_secret.shares).not_to eq secret.shares