Class: TFA::SecureStorage

Inherits:
Object
  • Object
show all
Defined in:
lib/tfa/secure_storage.rb

Instance Method Summary collapse

Constructor Details

#initialize(original, passphrase_request) ⇒ SecureStorage


3
4
5
6
# File 'lib/tfa/secure_storage.rb', line 3

def initialize(original, passphrase_request)
  @original = original
  @passphrase_request = passphrase_request
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/tfa/secure_storage.rb', line 42

def method_missing(name, *args, &block)
  super unless @original.respond_to?(name)

  was_encrypted = encrypted?
  if was_encrypted
    encrypted_content = IO.read(@original.path)
    decrypt!
    original_sha256 = Digest::SHA256.file(@original.path)
  end
  result = @original.public_send(name, *args, &block)
  if was_encrypted
    new_sha256 = Digest::SHA256.file(@original.path)

    if original_sha256 == new_sha256
      IO.write(@original.path, encrypted_content)
    else
      encrypt!
    end
  end
  result
end

Instance Method Details

#decrypt!Object


22
23
24
25
26
27
28
29
30
# File 'lib/tfa/secure_storage.rb', line 22

def decrypt!
  data = JSON.parse(IO.read(@original.path), symbolize_names: true)
  decipher = OpenSSL::Cipher.new(data[:algorithm])
  decipher.decrypt
  decipher.key = digest
  decipher.iv = Base64.decode64(data[:iv])
  plain_text = decipher.update(Base64.decode64(data[:cipher_text]))
  IO.write(@original.path, plain_text + decipher.final)
end

#encrypt!(algorithm = "AES-256-CBC") ⇒ Object


8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/tfa/secure_storage.rb', line 8

def encrypt!(algorithm = "AES-256-CBC")
  cipher = OpenSSL::Cipher.new(algorithm)
  cipher.encrypt
  cipher.key = digest
  cipher.iv = iv = cipher.random_iv
  plain_text = IO.read(@original.path)
  json = JSON.generate(
    algorithm: algorithm,
    iv: Base64.encode64(iv),
    cipher_text: Base64.encode64(cipher.update(plain_text) + cipher.final),
  )
  IO.write(@original.path, json)
end

#encrypted?Boolean


32
33
34
35
36
37
38
# File 'lib/tfa/secure_storage.rb', line 32

def encrypted?
  return false unless File.exist?(@original.path)
  JSON.parse(IO.read(@original.path))
  true
rescue JSON::ParserError
  false
end