Module: Lich::Common::GUI::MasterPasswordManager
- Defined in:
- documented/common/gui/master_password_manager.rb
Overview
Manages the storage and retrieval of the master password.
This module provides methods to store, retrieve, validate, and delete the master password using the system's keychain.
Constant Summary collapse
- KEYCHAIN_SERVICE =
'lich5.master_password'- VALIDATION_ITERATIONS =
100_000- VALIDATION_KEY_LENGTH =
32- VALIDATION_SALT_PREFIX =
'lich5-master-password-validation-v1'
Class Method Summary collapse
-
.create_validation_test(master_password) ⇒ Hash
Creates a validation test for the given master password.
-
.delete_master_password ⇒ Boolean
Deletes the master password from the keychain.
-
.keychain_available? ⇒ Boolean
Checks if the keychain is available on the current operating system.
-
.retrieve_master_password ⇒ String?
Retrieves the master password from the keychain.
-
.store_master_password(master_password) ⇒ Boolean
Stores the master password in the keychain.
-
.validate_master_password(entered_password, validation_test) ⇒ Boolean
Validates the entered master password against the stored validation test.
Class Method Details
.create_validation_test(master_password) ⇒ Hash
Creates a validation test for the given master password.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'documented/common/gui/master_password_manager.rb', line 88 def self.create_validation_test(master_password) random_salt = SecureRandom.random_bytes(16) full_salt = VALIDATION_SALT_PREFIX + random_salt validation_key = OpenSSL::PKCS5.pbkdf2_hmac( master_password, full_salt, VALIDATION_ITERATIONS, VALIDATION_KEY_LENGTH, OpenSSL::Digest.new('SHA256') ) validation_hash = OpenSSL::Digest::SHA256.digest(validation_key) { 'validation_salt' => Base64.strict_encode64(random_salt), 'validation_hash' => Base64.strict_encode64(validation_hash), 'validation_version' => 1 } end |
.delete_master_password ⇒ Boolean
Deletes the master password from the keychain.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'documented/common/gui/master_password_manager.rb', line 136 def self.delete_master_password return false unless keychain_available? if OS.mac? delete_macos_keychain elsif OS.linux? delete_linux_keychain elsif OS.windows? delete_windows_keychain else false end rescue StandardError => e Lich.log "error: Failed to delete master password: #{e.}" false end |
.keychain_available? ⇒ Boolean
Checks if the keychain is available on the current operating system.
30 31 32 33 34 35 36 37 38 39 40 |
# File 'documented/common/gui/master_password_manager.rb', line 30 def self.keychain_available? if OS.mac? macos_keychain_available? elsif OS.linux? linux_keychain_available? elsif OS.windows? windows_keychain_available? else false end end |
.retrieve_master_password ⇒ String?
Retrieves the master password from the keychain.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'documented/common/gui/master_password_manager.rb', line 66 def self.retrieve_master_password return nil unless keychain_available? if OS.mac? retrieve_macos_keychain elsif OS.linux? retrieve_linux_keychain elsif OS.windows? retrieve_windows_keychain else nil end rescue StandardError => e Lich.log "error: Failed to retrieve master password: #{e.}" nil end |
.store_master_password(master_password) ⇒ Boolean
Stores the master password in the keychain.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'documented/common/gui/master_password_manager.rb', line 46 def self.store_master_password(master_password) return false unless keychain_available? if OS.mac? store_macos_keychain(master_password) elsif OS.linux? store_linux_keychain(master_password) elsif OS.windows? store_windows_keychain(master_password) else false end rescue StandardError => e Lich.log "error: Failed to store master password: #{e.}" false end |
.validate_master_password(entered_password, validation_test) ⇒ Boolean
Validates the entered master password against the stored validation test.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'documented/common/gui/master_password_manager.rb', line 111 def self.validate_master_password(entered_password, validation_test) return false unless validation_test.is_a?(Hash) return false unless validation_test['validation_salt'] && validation_test['validation_hash'] begin random_salt = Base64.strict_decode64(validation_test['validation_salt']) stored_hash = Base64.strict_decode64(validation_test['validation_hash']) full_salt = VALIDATION_SALT_PREFIX + random_salt validation_key = OpenSSL::PKCS5.pbkdf2_hmac( entered_password, full_salt, VALIDATION_ITERATIONS, VALIDATION_KEY_LENGTH, OpenSSL::Digest.new('SHA256') ) computed_hash = OpenSSL::Digest::SHA256.digest(validation_key) secure_compare(computed_hash, stored_hash) rescue StandardError => e Lich.log "error: Validation failed: #{e.}" false end end |