fix(crypto): K-03 — emergency card persistence warning and rekey command
This commit is contained in:
+90
@@ -134,6 +134,13 @@ enum Commands {
|
||||
recovery_key: Option<String>,
|
||||
},
|
||||
|
||||
/// Erneuert den internen Verschlüsselungsschlüssel (DEK), verschlüsselt alle Chunks um und generiert ein neues Notfallblatt (K-03)
|
||||
Rekey {
|
||||
/// Pfad zur .sanctum Containerdatei
|
||||
#[arg(short, long)]
|
||||
path: PathBuf,
|
||||
},
|
||||
|
||||
/// Erstellt ein konsistentes Online-Backup (Hot-Backup) des laufenden Containers
|
||||
Backup {
|
||||
/// Pfad zur Quelldatei (.sanctum Containerdatei)
|
||||
@@ -879,6 +886,86 @@ fn handle_passwd(container_path: &Path, recovery_key: Option<&str>) -> Result<()
|
||||
println!(" • KDF: Argon2id mit frischem Salt");
|
||||
println!(" • Status: DEK sicher neu verpackt (alle Chunks intakt)");
|
||||
println!();
|
||||
println!(" [!] HINWEIS: Das 24-Wörter-Notfallblatt bleibt weiterhin gültig!");
|
||||
println!(" Um den Container vollständig mit neuem Master-Schlüssel zu sichern,");
|
||||
println!(" nutzen Sie `sanctum rekey`.");
|
||||
println!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_rekey(container_path: &Path) -> Result<()> {
|
||||
if !container_path.exists() {
|
||||
bail!(
|
||||
"Containerdatei '{}' existiert nicht.",
|
||||
container_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
println!("┌─────────────────────────────────────────────────────────────┐");
|
||||
println!("│ Sanctum — Master-Schlüssel erneuern (Rekeying) │");
|
||||
println!("└─────────────────────────────────────────────────────────────┘");
|
||||
println!(" Container: {}", container_path.display());
|
||||
println!();
|
||||
println!(" [!] WICHTIGER SICHERHEITSHINWEIS (K-03):");
|
||||
println!(" Beim Rekeying wird der interne Daten-Verschlüsselungsschlüssel (DEK)");
|
||||
println!(" neu generiert und alle Datenblöcke werden umverschlüsselt.");
|
||||
println!(" Das bisherige 24-Wörter-Notfallblatt wird damit UNWIDERRUFLICH UNGÜLTIG.");
|
||||
println!();
|
||||
|
||||
let password = Zeroizing::new(
|
||||
rpassword::prompt_password("Master-Passwort des Containers eingeben: ")
|
||||
.context("Fehler beim Einlesen des Master-Passworts")?,
|
||||
);
|
||||
|
||||
if password.trim().is_empty() {
|
||||
bail!("Das Master-Passwort darf nicht leer sein.");
|
||||
}
|
||||
|
||||
println!();
|
||||
ui::step(
|
||||
1,
|
||||
3,
|
||||
"🔄",
|
||||
"Entschlüssele Datenblöcke & verschlüssele mit neuem DEK...",
|
||||
);
|
||||
let new_phrase = sanctum::recovery::rekey_container(container_path, &password)
|
||||
.context("Fehler beim Ausführen des Rekeyings")?;
|
||||
ui::step(
|
||||
2,
|
||||
3,
|
||||
"🔒",
|
||||
"Aktualisiere Container-Header & Metadaten-Authentifizierung...",
|
||||
);
|
||||
ui::step(3, 3, "🔑", "Generiere neues 24-Wort BIP-39 Notfallblatt...");
|
||||
|
||||
println!();
|
||||
println!("┌─────────────────────────────────────────────────────────────┐");
|
||||
println!("│ ✔ Container erfolgreich rekeyed! │");
|
||||
println!("└─────────────────────────────────────────────────────────────┘");
|
||||
println!();
|
||||
println!(" • Container: {}", container_path.display());
|
||||
println!(" • Status: Alle Chunks wurden unter einem frischen DEK neu verschlüsselt.");
|
||||
println!(" • Alt-Schlüssel:Bisheriges Notfallblatt ist ab sofort ungültig und entwertet.");
|
||||
println!();
|
||||
println!("┌─────────────────────────────────────────────────────────────┐");
|
||||
println!("│ NEUES 24-WORT BIP-39 NOTFALLBLATT (NOTFALL-WIEDERHERSTELLUNG)│");
|
||||
println!("└─────────────────────────────────────────────────────────────┘");
|
||||
println!();
|
||||
let words: Vec<&str> = new_phrase.split_whitespace().collect();
|
||||
for (i, chunk) in words.chunks(4).enumerate() {
|
||||
let line = chunk
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(j, w)| format!("{:2}. {:<12}", i * 4 + j + 1, w))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
println!(" {}", line);
|
||||
}
|
||||
println!();
|
||||
println!(" [!] WICHTIG: Drucken Sie diese Wörter aus oder notieren Sie sie sicher.");
|
||||
println!(" Das alte Notfallblatt kann nicht mehr zur Wiederherstellung verwendet werden.");
|
||||
println!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1573,6 +1660,9 @@ async fn run() -> Result<()> {
|
||||
Commands::UpgradeFormat { path } => {
|
||||
handle_upgrade_format(&path)?;
|
||||
}
|
||||
Commands::Rekey { path } => {
|
||||
handle_rekey(&path)?;
|
||||
}
|
||||
Commands::Sync {
|
||||
path,
|
||||
source,
|
||||
|
||||
Reference in New Issue
Block a user