diff options
| author | mo <mo.khan@gmail.com> | 2018-02-11 12:51:34 -0700 |
|---|---|---|
| committer | mo <mo.khan@gmail.com> | 2018-02-11 12:51:34 -0700 |
| commit | 6d0636f3833454f5764b3bfe54759f01f43cb920 (patch) | |
| tree | dcf7cd2ebe7efd3270b6191443df79bc5eb765d9 | |
| parent | 4eb9e1df2af3d07b711c8cb4afefbaaa324f4afd (diff) | |
extract class to encrypt/decrypt db on demand.
| -rw-r--r-- | lib/tfa.rb | 1 | ||||
| -rw-r--r-- | lib/tfa/cli.rb | 30 | ||||
| -rw-r--r-- | lib/tfa/secure_proxy.rb | 53 | ||||
| -rw-r--r-- | lib/tfa/storage.rb | 36 |
4 files changed, 61 insertions, 59 deletions
@@ -6,6 +6,7 @@ require "rotp" require "yaml/store" require "tfa/cli" +require "tfa/secure_proxy" require "tfa/storage" require "tfa/totp_command" require "tfa/version" diff --git a/lib/tfa/cli.rb b/lib/tfa/cli.rb index f88eb67..01682eb 100644 --- a/lib/tfa/cli.rb +++ b/lib/tfa/cli.rb @@ -9,31 +9,23 @@ module TFA desc "add NAME SECRET", "add a new secret to the database" def add(name, secret) - open_database do - storage.save(name, clean(secret)) - end + storage.save(name, clean(secret)) "Added #{name}" end desc "destroy NAME", "remove the secret associated with the name" def destroy(name) - open_database do - storage.delete(name) - end + storage.delete(name) end desc "show NAME", "shows the secret for the given key" def show(name = nil) - open_database do - name ? storage.secret_for(name) : storage.all - end + name ? storage.secret_for(name) : storage.all end desc "totp NAME", "generate a Time based One Time Password using the secret associated with the given NAME." def totp(name = nil) - open_database do - TotpCommand.new(storage).run(name) - end + TotpCommand.new(storage).run(name) end desc "now SECRET", "generate a Time based One Time Password for the given secret" @@ -58,7 +50,6 @@ module TFA yaml_storage.save(name, secret) if yes?("Migrate `#{name}`?") end end - yaml_storage.encrypt!(passphrase) File.delete(pstore_path) if yes?("Delete `#{pstore_path}`?") end end @@ -67,14 +58,14 @@ module TFA def encrypt return unless ensure_upgraded! - yaml_storage.encrypt!(passphrase) + yaml_storage.encrypt! end desc "decrypt", "decrypts the tfa database" def decrypt return unless ensure_upgraded! - yaml_storage.decrypt!(passphrase) + yaml_storage.decrypt! end private @@ -88,7 +79,7 @@ module TFA end def yaml_storage - @yaml_storage ||= Storage.new(yaml_path) + @yaml_storage ||= SecureProxy.new(Storage.new(yaml_path), passphrase) end def filename @@ -131,12 +122,5 @@ module TFA def upgraded? !File.exist?(pstore_path) && File.exist?(yaml_path) end - - def open_database - yaml_storage.decrypt!(passphrase) if upgraded? - result = yield - yaml_storage.encrypt!(passphrase) - result - end end end diff --git a/lib/tfa/secure_proxy.rb b/lib/tfa/secure_proxy.rb new file mode 100644 index 0000000..0c18d83 --- /dev/null +++ b/lib/tfa/secure_proxy.rb @@ -0,0 +1,53 @@ +module TFA + class SecureProxy + def initialize(original, passphrase) + @original = original + @digest = Digest::SHA256.digest(passphrase) + end + + def encrypt! + cipher = OpenSSL::Cipher.new("AES-256-CBC") + cipher.encrypt + cipher.key = @digest + #iv = cipher.random_iv + #cipher.iv = iv + + plain_text = read_all + #cipher_text = iv + cipher.update(plain_text) + cipher.final + cipher_text = cipher.update(plain_text) + cipher.final + flush(cipher_text) + end + + def decrypt! + return unless File.exist?(@original.path) + + cipher_text = read_all + decipher = OpenSSL::Cipher.new("AES-256-CBC") + decipher.decrypt + #decipher.iv = cipher_text[0..decipher.iv_len-1] + decipher.key = @digest + #data = cipher_text[decipher.iv_len..-1] + data = cipher_text + flush(decipher.update(data) + decipher.final) + end + + private + + def method_missing(name, *args, &block) + super unless @original.respond_to?(name) + + decrypt! + result = @original.public_send(name, *args, &block) + encrypt! + result + end + + def read_all + IO.read(@original.path) + end + + def flush(data) + IO.write(@original.path, data) + end + end +end diff --git a/lib/tfa/storage.rb b/lib/tfa/storage.rb index c2caf27..02f8961 100644 --- a/lib/tfa/storage.rb +++ b/lib/tfa/storage.rb @@ -43,30 +43,6 @@ module TFA end end - def encrypt!(passphrase) - cipher = OpenSSL::Cipher.new("AES-256-CBC") - cipher.encrypt - cipher.key = digest_for(passphrase) - #iv = cipher.random_iv - #cipher.iv = iv - - plain_text = read_all - #cipher_text = iv + cipher.update(plain_text) + cipher.final - cipher_text = cipher.update(plain_text) + cipher.final - flush(cipher_text) - end - - def decrypt!(passphrase) - cipher_text = read_all - decipher = OpenSSL::Cipher.new("AES-256-CBC") - decipher.decrypt - #decipher.iv = cipher_text[0..decipher.iv_len-1] - decipher.key = digest_for(passphrase) - #data = cipher_text[decipher.iv_len..-1] - data = cipher_text - flush(decipher.update(data) + decipher.final) - end - private def open_readonly @@ -74,17 +50,5 @@ module TFA yield @storage end end - - def read_all - IO.read(path) - end - - def flush(data) - IO.write(path, data) - end - - def digest_for(passphrase) - Digest::SHA256.digest(passphrase) - end end end |
