Class: Aspera::Keychain::EncryptedHash
- Defined in:
- lib/aspera/keychain/encrypted_hash.rb
Overview
Manage secrets in a simple Hash
Defined Under Namespace
Classes: OsslCipher
Constant Summary
Constants inherited from Base
Instance Method Summary collapse
- #all ⇒ Object
- #change_password(password) ⇒ Object
- #delete(label:) ⇒ Object
- #get(label:, exception: true) ⇒ Object
- #info ⇒ Object
-
#initialize(file:, password:) ⇒ EncryptedHash
constructor
A new instance of EncryptedHash.
-
#set(options) ⇒ Object
set a secret.
Methods inherited from Base
Constructor Details
#initialize(file:, password:) ⇒ EncryptedHash
Returns a new instance of EncryptedHash.
28 29 30 31 32 33 34 35 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 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 28 def initialize(file:, password:) super() Aspera.assert_type(file, String) { 'path to vault file' } @path = file Log.dump(:vault_file, @path) @all_secrets = {} @cipher_name = DEFAULT_CIPHER_NAME @kdf_params = nil # true when the vault was created by v4.26.0 (password padded with zeros, no KDF) @legacy_key = false vault_encrypted_data = nil Log.dump(:vault_file, File.(@path)) if File.exist?(@path) vault_file = File.read(@path) if vault_file.start_with?('---') vault_info = YAML.parse(vault_file).to_ruby sorted_keys = vault_info.keys.sort Aspera.assert(sorted_keys == FILE_KEYS || sorted_keys == FILE_KEYS_KDF) { "Invalid vault file: #{@path}: #{sorted_keys}" } @cipher_name = vault_info['cipher'] @kdf_params = vault_info['kdf'] # vault created before PBKDF2 was introduced (v4.26.0 format: no kdf field) @legacy_key = @kdf_params.nil? vault_encrypted_data = vault_info['data'] else # legacy vault file (binary, pre-YAML format) @cipher_name = LEGACY_CIPHER_NAME @legacy_key = true vault_encrypted_data = File.read(@path, mode: 'rb') end end # setting password also creates the cipher @cipher = cipher(password) @all_secrets = Yaml.safe_load(@cipher.decrypt(vault_encrypted_data)) || {} if !vault_encrypted_data.nil? end |
Instance Method Details
#all ⇒ Object
69 70 71 72 73 74 75 76 77 78 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 69 def all result = [] @all_secrets.each do |label, values| normal = values.symbolize_keys normal[:label] = label CONTENT_KEYS.each { |k| normal[k] = '' unless normal.key?(k) } result.push(normal) end return result end |
#change_password(password) ⇒ Object
102 103 104 105 106 107 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 102 def change_password(password) # Generate new KDF params so a password change also re-salts the vault @kdf_params = nil @cipher = cipher(password) save end |
#delete(label:) ⇒ Object
97 98 99 100 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 97 def delete(label:) @all_secrets.delete(label) save end |
#get(label:, exception: true) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 90 def get(label:, exception: true) Aspera.assert(@all_secrets.key?(label)) { "Label not found: #{label}" } if exception result = @all_secrets[label].clone result[:label] = label if result.is_a?(Hash) return result end |
#info ⇒ Object
63 64 65 66 67 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 63 def info return { file: @path } end |