pub struct CredentialStore {
using_keyring: bool,
credentials_path: PathBuf,
encryption_key: [u8; 32],
legacy_key: [u8; 32],
}Expand description
Credential storage manager
Fields§
§using_keyring: boolWhether we’re using keyring (true) or encrypted file (false)
credentials_path: PathBufPath to the encrypted credentials file (fallback)
encryption_key: [u8; 32]Encryption key for the file fallback. Random and persisted, so it does not change when the machine is renamed.
legacy_key: [u8; 32]The pre-existing derivation, retained only to read a file written before
the key was persisted. Anything decrypted with it is rewritten under
encryption_key.
Implementations§
Source§impl CredentialStore
impl CredentialStore
Sourcepub fn is_using_keyring(&self) -> bool
pub fn is_using_keyring(&self) -> bool
Check if we’re using the secure keyring backend
Sourcepub fn save_token(
&self,
user_id: &str,
token: &str,
) -> Result<CredentialResult, CredentialError>
pub fn save_token( &self, user_id: &str, token: &str, ) -> Result<CredentialResult, CredentialError>
Save an access token for a user
Sourcepub fn get_token(&self, user_id: &str) -> Result<String, CredentialError>
pub fn get_token(&self, user_id: &str) -> Result<String, CredentialError>
Get an access token for a user
Sourcepub fn delete_token(&self, user_id: &str) -> Result<(), CredentialError>
pub fn delete_token(&self, user_id: &str) -> Result<(), CredentialError>
Delete an access token for a user
fn test_keyring_available() -> bool
fn test_keyring_inner() -> bool
fn save_to_keyring( &self, user_id: &str, token: &str, ) -> Result<(), CredentialError>
fn get_from_keyring(&self, user_id: &str) -> Result<String, CredentialError>
fn delete_from_keyring(&self, user_id: &str) -> Result<(), CredentialError>
Sourcefn get_key_path() -> PathBuf
fn get_key_path() -> PathBuf
Where the fallback key lives: beside the credentials file, so the two travel together and a restore that brings one brings the other.
fn get_credentials_path() -> PathBuf
Sourcefn derive_legacy_encryption_key() -> [u8; 32]
fn derive_legacy_encryption_key() -> [u8; 32]
The key derivation used before keys were persisted.
Kept only so a credentials file written by an older build can still be read once and rewritten under the persisted key. Never used to encrypt. See the module docs for why it was replaced.
TRACES: UR-012 | IR-014
Sourcefn load_credentials_file(&self) -> Result<Value, CredentialError>
fn load_credentials_file(&self) -> Result<Value, CredentialError>
Load and decrypt the credential map.
A file that is present but undecryptable is deliberately reported as an empty credential set rather than as an error. The key never leaves the device it was derived on (Android Keystore keys are never backed up, and the file fallback’s key is derived from machine identifiers), so a restored/transferred install gets ciphertext with no key and every read would fail permanently. Surfacing that as an error made session restore throw instead of falling back to the login screen: an unrecoverable app rather than a clean logged-out one. The next successful login re-encrypts the file with the current key, so the state self-heals.
TRACES: UR-012 | IR-014
fn save_credentials_file(&self, data: &Value) -> Result<(), CredentialError>
fn encrypt(&self, plaintext: &str) -> Result<String, CredentialError>
Sourcefn decrypt_migrating(
&self,
encrypted: &str,
) -> Result<(String, bool), CredentialError>
fn decrypt_migrating( &self, encrypted: &str, ) -> Result<(String, bool), CredentialError>
Decrypt with the current key, falling back to the legacy derivation.
Returns the plaintext and whether the legacy key was what opened it, so the caller can rewrite the file under the current key and stop depending on a derivation that changes when the machine is renamed.
TRACES: UR-012 | IR-014 | UT-014