pkcs11-daemon is a persistent background service that bootstraps cryptographic key material at startup and exposes it for use by other system components. It coordinates three sub-components: a SQLite-backed Vault for key persistence, a Crypto engine for key generation, and an SDImporter for importing keys from removable storage.
Architecture overview
Vault
SQLite-backed key store. Persists key label, type, and PEM data to
vault.db.Crypto engine
Generates RSA 2048-bit keys via OpenSSL EVP. Post-quantum generation is stubbed.
SDImporter
Background thread that polls
/media/sdcard0–2 for SD cards and imports their keys into the Vault.Startup sequence
The daemon entry point indaemon.cpp runs the following sequence:
Open the Vault
daemon.cpp
vault.db and runs CREATE TABLE IF NOT EXISTS keys to ensure the schema exists.Start the SD card watcher
daemon.cpp
SDImporter::watch_ports on a detached background thread.Generate default RSA key
daemon.cpp
"default-rsa".Generate default PQC key
daemon.cpp
"default-pq" with type "dilithium".Vault
TheVault class (vault.h / vault.cpp) wraps a SQLite3 database.
Schema
| Column | Type | Description |
|---|---|---|
label | TEXT PRIMARY KEY | Human-readable key identifier (e.g., "default-rsa"). |
type | TEXT | Algorithm family string (e.g., "rsa", "dilithium"). |
data | TEXT | PEM-encoded key material or empty string for stubs. |
API
Opens the SQLite database at
path. Uses sqlite3_open internally.Parameter: path (const std::string&) — filesystem path to the database file (e.g., "vault.db").Runs the
CREATE TABLE IF NOT EXISTS keys DDL statement. Safe to call on an existing database.Inserts or replaces a key row using
INSERT OR REPLACE INTO keys.Parameters: label — key identifier; type — algorithm string; data — key material.Returns the
data column for the given label, or an empty string if no matching row exists.Parameter: label (const std::string&) — key identifier to look up.Crypto engine
TheCrypto class (crypto.h / crypto.cpp) provides static factory methods for key generation.
generate_rsa()
Generates a 2048-bit RSA key pair using the OpenSSL EVP API and returns the PEM-encoded private key as a std::string.
crypto.cpp
pqc_generate()
crypto.cpp
SDImporter
TheSDImporter class (sd_import.h / sd_import.cpp) watches three SD card mount points in a background thread.
watch_ports()
Runs an infinite polling loop with a 10-second sleep between iterations. On each pass it checks whether any of the following paths exist using std::filesystem::exists:
/media/sdcard0/media/sdcard1/media/sdcard2
sd_import.cpp
The actual key import logic is not yet implemented (marked
TODO). Detection is working, but keys are not yet read from or written to the Vault from this path.Build requirements
| Dependency | Required | Notes |
|---|---|---|
| C++17 compiler | Yes | std::filesystem support required. |
| CMake 3.20+ | Yes | — |
| OpenSSL (libssl, libcrypto) | Yes | Used by Crypto::generate_rsa() via the EVP API. |
| SQLite3 | Yes | Used by Vault for key persistence. |
| liboqs | Optional | Required for Crypto::pqc_generate() when implemented. |