mirror of
https://github.com/NotAShelf/stash.git
synced 2026-06-09 14:54:26 +00:00
db: remove unnecessary identity cache from decrypt_cached
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I9228809562cc9b2f7c0a9d7ece9f5ada6a6a6964
This commit is contained in:
parent
656709bd19
commit
384ac708eb
1 changed files with 15 additions and 17 deletions
|
|
@ -1218,6 +1218,11 @@ fn load_sensitive_regex() -> Option<Regex> {
|
|||
/// previously encrypted entries permanently undecryptable, so the permanent
|
||||
/// cache prevents accidental passphrase changes from corrupting the
|
||||
/// clipboard history.
|
||||
///
|
||||
/// Removing the passphrase entirely (disabling encryption) after entries have
|
||||
/// been stored encrypted also renders those entries permanently unreadable.
|
||||
/// There is no migration path short of wiping the database. `stash stats`
|
||||
/// reports affected entries as Undecryptable.
|
||||
#[cfg(feature = "encryption")]
|
||||
fn load_encryption_passphrase() -> Option<age::secrecy::SecretString> {
|
||||
use std::process::Command;
|
||||
|
|
@ -1250,25 +1255,18 @@ fn load_encryption_passphrase() -> Option<age::secrecy::SecretString> {
|
|||
Some(secret)
|
||||
}
|
||||
|
||||
/// Decrypt age-encrypted data using a cached scrypt identity.
|
||||
/// Decrypt age-encrypted data.
|
||||
///
|
||||
/// `age::scrypt::Identity::new` is cheap since it stores the passphrase only.
|
||||
/// The scrypt KDF runs inside `age::decrypt` per call, on the per-file salt
|
||||
/// embedded in the ciphertext header. Caching the Identity would not avoid
|
||||
/// it. The passphrase itself is cached by [`load_encryption_passphrase`].
|
||||
#[cfg(feature = "encryption")]
|
||||
fn decrypt_cached(ciphertext: &[u8]) -> Result<Vec<u8>, StashError> {
|
||||
static CACHE: OnceLock<Mutex<Option<age::scrypt::Identity>>> =
|
||||
OnceLock::new();
|
||||
let cache = CACHE.get_or_init(|| Mutex::new(None));
|
||||
let mut guard = cache.lock().map_err(|e| {
|
||||
StashError::Decryption(format!("identity cache lock poisoned: {e}").into())
|
||||
})?;
|
||||
if guard.is_none() {
|
||||
let passphrase = load_encryption_passphrase().ok_or_else(|| {
|
||||
StashError::Decryption("no passphrase configured".into())
|
||||
})?;
|
||||
*guard = Some(age::scrypt::Identity::new(passphrase));
|
||||
}
|
||||
let identity = guard
|
||||
.as_ref()
|
||||
.ok_or_else(|| StashError::Decryption("identity not available".into()))?;
|
||||
age::decrypt(identity, ciphertext)
|
||||
let passphrase = load_encryption_passphrase()
|
||||
.ok_or_else(|| StashError::Decryption("no passphrase configured".into()))?;
|
||||
let identity = age::scrypt::Identity::new(passphrase);
|
||||
age::decrypt(&identity, ciphertext)
|
||||
.map_err(|e| StashError::Decryption(e.to_string().into()))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue