Class: Arver::KeySaver

Inherits:
Object
  • Object
show all
Defined in:
lib/arver/key_saver.rb

Class Method Summary collapse

Class Method Details

.add(user, key) ⇒ Object



15
16
17
18
19
# File 'lib/arver/key_saver.rb', line 15

def self.add( user, key )
  path     = key_path( user )
  filename = save_to( user, key, path )
  File.join(path,filename)
end

.add_padding(key) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/arver/key_saver.rb', line 117

def self.add_padding( key )
  marker = "--"+ActiveSupport::SecureRandom.base64( 82 )
  size = 200000
  padding_size = size - key.size
  if padding_size <= 0
    padding_size = 0
    Arver::Log.warn( "Warning: Your arver keys exceed the maximal padding size, therefore i can no longer disguise how many keys you possess.")
  end
  padding = ActiveSupport::SecureRandom.base64( padding_size )[0..padding_size]
  marker +"\n"+ key + "\n" + marker + "\n" + padding
end

.backup_key_path(user) ⇒ Object



70
71
72
# File 'lib/arver/key_saver.rb', line 70

def self.backup_key_path( user )
  "#{key_path(user)}.bak"
end

.config_pathObject



78
79
80
# File 'lib/arver/key_saver.rb', line 78

def self.config_path
  Arver::LocalConfig.instance.config_dir
end

.deflate(string, level = 6) ⇒ Object



21
22
23
24
25
26
# File 'lib/arver/key_saver.rb', line 21

def self.deflate(string, level=6)
  z = Zlib::Deflate.new(level)
  dst = z.deflate(string, Zlib::FINISH)
  z.close
  dst
end

.inflate(string) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/arver/key_saver.rb', line 28

def self.inflate(string)
  zstream = Zlib::Inflate.new
  buf = zstream.inflate(string)
  zstream.finish
  zstream.close
  buf
end

.key_path(user) ⇒ Object



66
67
68
# File 'lib/arver/key_saver.rb', line 66

def self.key_path( user )
  File.join("#{config_path}","keys","#{user}")
end

.num_of_key_files(user) ⇒ Object



86
87
88
# File 'lib/arver/key_saver.rb', line 86

def self.num_of_key_files( user )
  Dir.entries( key_path( user ) ).size - 2
end

.purge_keys(user) ⇒ Object



82
83
84
# File 'lib/arver/key_saver.rb', line 82

def self.purge_keys( user )
  FileUtils.rm_rf( key_path( user ) )
end

.read(user) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/arver/key_saver.rb', line 90

def self.read( user )
  GPGKeyManager.check_key_of( user )
  return [] unless File.exists?( key_path( user ) )
  decrypted = []
  crypto = GPGME::Crypto.new
  Dir.entries( key_path( user ) ).sort.each do | file |
    unless( file == "." || file == ".." )
      Arver::Log.trace( "Loading keyfile "+file )
      key_encrypted = File.open( File.join( key_path( user ),file) )
      begin
        decrypted_txt = crypto.decrypt( key_encrypted, { :passphrase_callback => method( :passfunc ) } )
      rescue GPGME::Error => gpgerr
        Arver::Log.error( "GPGME Error #{gpgerr} Message: #{gpgerr.message}" )
        next
      end
      decrypted_key = substract_padding( decrypted_txt.read )
      begin
        decrypted_key = inflate( decrypted_key )
      rescue Zlib::DataError
        Log.write("You have an outdated key. Run garbage collect to update it.")
      end
      decrypted += [ decrypted_key ];
    end
  end
  decrypted
end

.save(user, key) ⇒ Object



4
5
6
7
8
9
10
11
12
13
# File 'lib/arver/key_saver.rb', line 4

def self.save( user, key )
  tmp_path  = tmp_key_path( user )
  back_path = backup_key_path( user )
  path      = key_path( user )
  filename  = save_to( user, key, tmp_path )
  FileUtils.mv(path,back_path) if File.exists?(path) 
  FileUtils.mv(tmp_path,path)
  FileUtils.rm_rf(back_path)
  File.join(path,filename)
end

.save_to(user, key, path) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/arver/key_saver.rb', line 36

def self.save_to( user, key, path )
  #compress the key before applying padding, so the size after encryption+compression by gpg is more stable...
  key = deflate(key)
  unless GPGKeyManager.check_key_of( user )
    return
  end
  gpg_key = GPGKeyManager.key_of( user )
  key = add_padding( key )
  crypto = GPGME::Crypto.new :armor => true
  begin
    if( Arver::RuntimeConfig.instance.trust_all )
      encrypted = crypto.encrypt( key, {:recipients => gpg_key.fingerprint, :always_trust => true})
    else
      encrypted = crypto.encrypt( key, {:recipients => gpg_key.fingerprint, :armor => true})
    end
  rescue GPGME::Error => gpgerr
    Arver::Log.error( "GPGME Error #{gpgerr} Message: #{gpgerr.message}" )
    return
  end
  key_encrypted = encrypted.read
  unless( Arver::RuntimeConfig.instance.dry_run )
    FileUtils.mkdir_p path unless File.exists?( path )
    filename = "#{OpenSSL::Digest::SHA256.new << key_encrypted}"
    File.open( File.join("#{path}","#{filename}"), 'w' ) do |f|
      f.write key_encrypted
    end
  end
  filename
end

.substract_padding(key) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/arver/key_saver.rb', line 129

def self.substract_padding( key )
  if( key.starts_with? '--- ' )
    Arver::Log.warn( "Warning: you are using deprecated unpadded keyfiles. Please run garbage collect!" )
    return key
  end
  marker = ""
  striped_key = ""
  key.each_line do |line|
    if( marker.empty? )
       marker = line
    elsif( line == marker )
      break
    else
      striped_key += line
    end
  end
  striped_key.chomp
end

.tmp_key_path(user) ⇒ Object



74
75
76
# File 'lib/arver/key_saver.rb', line 74

def self.tmp_key_path( user )
  File.join("#{config_path}","tmp","#{user}")
end