
Gestore di password crittografato local-first per accessi, note e chiavi API, che utilizza un vault SQLite protetto con Argon2id e XChaCha20-Poly1305; nessun cloud né telemetria.
GTK4 / gtkmm-4 · C++23 · CMake · SQLite · libsodium
lsPass archivia credenziali di accesso, note sicure e chiavi API in una cassaforte locale cifrata. Nessuna rete, nessun cloud, nessuna telemetria. Nessun segreto viene mai scritto su disco in chiaro.
sudo apt install libgtkmm-4.0-dev libsqlite3-dev libsodium-dev nlohmann-json3-dev
cmake -B build
cmake --build build -j
ctest --test-dir build --output-on-failure # 41 unit tests
./build/lspass
La cassaforte si trova in ~/.local/share/lspass/vault.db (permessi 0600).
cmake -B build-rel -DCMAKE_BUILD_TYPE=Release
cmake --build build-rel -j
cd build-rel && cpack -G DEB # requires: dpkg-dev, file
sudo dpkg -i ../packages/deb/lspass_1.0.0_amd64.deb
Il .deb finisce in packages/deb/ e include il binario, una voce di avvio com.lspass.App.desktop e l'icona dell'app (packaging/com.lspass.App.svg, installata nel tema hicolor).
cmake --install senza CPack usa il prefisso predefinito /usr/local. Le dipendenze runtime (libgtkmm-4.0, libsodium, libsqlite3, …) vengono risolte automaticamente da dpkg-shlibdeps, quindi apt --fix-broken install o sudo apt install ./lspass_1.0.0_amd64.deb recupera tutto il necessario.
Basata sull'OWASP Password Storage Cheat Sheet, sulla documentazione di libsodium e sul pattern di cifratura a busta (envelope encryption) usato da gestori di password affermati (key wrapping stile Bitwarden, KeePassXC):
master password
│ Argon2id (memory-hard KDF, random 128-bit salt,
▼ opslimit/memlimit = libsodium "moderate",
KEK (32 B) parameters stored in vault for future upgrades)
│ XChaCha20-Poly1305 (key wrap)
▼
DEK (32 B, random) ── wraps nothing else, RAM only, never on disk
│ XChaCha20-Poly1305 AEAD per field
▼
SQLite: entries(title, username, url [plaintext metadata],
secret, notes [sealed blobs: nonce‖ct‖poly1305 tag])
Perché queste scelte:
Compromesso onesto: title, username e url sono memorizzati in chiaro, così l'elenco/ricerca funziona senza decifrare ogni riga. I segreti stessi (password, note, chiavi API) sono sempre blob sigillati. Il test unitario secrets_not_stored_in_plaintext esegue una scansione byte per byte del file della cassaforte (incl. WAL) alla ricerca di un segreto canarino per dimostrarlo.
ctest esegue tre suite (41 casi) contro la libreria core indipendente dalla GUI. L'intera suite viene anche eseguita con AddressSanitizer + UBSan:
cmake -B build-san -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined"
cmake --build build-san -j && ctest --test-dir build-san
Le build Release aggiungono -fstack-protector-strong, -D_FORTIFY_SOURCE=2, PIE e RELRO completo (-Wl,-z,relro,-z,now).
src/core/crypto.{hpp,cpp} SecureBytes, Argon2id KDF, XChaCha20-Poly1305, key wrap
src/core/vault.{hpp,cpp} SQLite vault, envelope encryption, CRUD
src/core/generator.{hpp,cpp} CSPRNG password/passphrase generator
src/ui/ gtkmm-4 UI (unlock screen, list, editor dialogs)
tests/ ctest suites (no external framework needed)
MIT — vedi LICENSE.
| Decisione | Motivazione |
|---|
| Argon2id KDF | Prima scelta OWASP per le chiavi derivate da password; memory-hard, resistente al cracking con GPU/ASIC. I parametri superano il minimo OWASP (m ≥ 19 MiB, t = 2). |
| Envelope encryption (DEK casuale avvolto da KEK) | Cambiare la password principale richiede solo di ri-avvolgere 32 byte invece di ri-cifrare l'intera cassaforte; compromettere il DEK è impossibile senza il KEK. |
| XChaCha20-Poly1305 AEAD | I nonce casuali a 192 bit rendono il riuso dei nonce un problema inesistente; Poly1305 autentica ogni testo cifrato, quindi una password principale errata viene rilevata da un errore di autenticazione — non viene mai memorizzato alcun hash o verificatore della password da nessuna parte. |
Binding AAD (lspass:v1:entry:<id>:<field>) | I testi cifrati non possono essere trasferiti tra voci o campi da un attaccante con accesso in scrittura al file del DB. |
| Nonce fresco a ogni scrittura | Ogni salvataggio ri-sigilla con un nuovo nonce casuale. |
| Igiene della memoria | Le chiavi risiedono in SecureBytes, azzerate con sodium_memzero alla distruzione; la UI pulisce i campi password subito dopo l'uso; la clipboard si svuota automaticamente 30 s dopo la copia (e solo se contiene ancora il nostro segreto). |
| Permessi dei file | Il file della cassaforte è chmod 0600. |
| Generatore di password | CSPRNG del kernel con campionamento per reiezione (nessun bias del modulo), garantisce tutte le classi di caratteri abilitate, esclude per impostazione predefinita i glifi ambigui; ~128 bit di entropia con i 20 caratteri predefiniti. |