fix(cli): init stages salt, handles --output ..-paths, zeroizes image_secret
1. Add .relicario/salt to the initial git commit so it syncs across devices (Argon2 salt must match at unlock time). 2. Return a proper error instead of panicking when --output has no filename component (e.g., trailing ..). 3. Wrap the generated 32-byte image_secret in Zeroizing for consistency with the passphrase + master_key handling in Task 4. Caught in Task 6 review.
This commit is contained in:
@@ -282,11 +282,14 @@ fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> {
|
||||
}
|
||||
|
||||
// Image secret: 32 random bytes, embedded in the carrier.
|
||||
let mut image_secret = [0u8; 32];
|
||||
OsRng.fill_bytes(&mut image_secret);
|
||||
let image_secret = {
|
||||
let mut buf = Zeroizing::new([0u8; 32]);
|
||||
OsRng.fill_bytes(buf.as_mut_slice());
|
||||
buf
|
||||
};
|
||||
let carrier = fs::read(&image)
|
||||
.with_context(|| format!("failed to read carrier image {}", image.display()))?;
|
||||
let stego = imgsecret::embed(&carrier, &image_secret)?;
|
||||
let stego = imgsecret::embed(&carrier, &*image_secret)?;
|
||||
fs::write(&output, &stego)
|
||||
.with_context(|| format!("failed to write reference image {}", output.display()))?;
|
||||
|
||||
@@ -296,7 +299,7 @@ fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> {
|
||||
let params = KdfParams { argon2_m: 65536, argon2_t: 3, argon2_p: 4 };
|
||||
|
||||
// Derive master key, then persist an empty Manifest + default VaultSettings.
|
||||
let master_key = derive_master_key(passphrase.as_bytes(), &image_secret, &salt, ¶ms)?;
|
||||
let master_key = derive_master_key(passphrase.as_bytes(), &*image_secret, &salt, ¶ms)?;
|
||||
|
||||
fs::create_dir_all(&relicario_dir)?;
|
||||
fs::create_dir_all(root.join("items"))?;
|
||||
@@ -324,7 +327,10 @@ fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> {
|
||||
fs::write(root.join("settings.enc"), encrypt_settings(&settings, &master_key)?)?;
|
||||
|
||||
// .gitignore excludes the reference image.
|
||||
let gitignore = format!("{}\n", output.file_name().unwrap().to_string_lossy());
|
||||
let fname = output.file_name()
|
||||
.ok_or_else(|| anyhow::anyhow!("output path has no filename: {}", output.display()))?
|
||||
.to_string_lossy();
|
||||
let gitignore = format!("{fname}\n");
|
||||
fs::write(root.join(".gitignore"), gitignore)?;
|
||||
|
||||
// git init + initial commit via hardened wrapper.
|
||||
@@ -332,7 +338,7 @@ fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> {
|
||||
if !status.success() { anyhow::bail!("git init failed"); }
|
||||
let _ = crate::helpers::git_command(&root, &[
|
||||
"add", ".gitignore", ".relicario/params.json", ".relicario/devices.json",
|
||||
"manifest.enc", "settings.enc",
|
||||
".relicario/salt", "manifest.enc", "settings.enc",
|
||||
]).status()?;
|
||||
let status = crate::helpers::git_command(&root, &[
|
||||
"commit", "-m", "init: new relicario vault (format v2)",
|
||||
|
||||
Reference in New Issue
Block a user