feat(cli): init --key-file generates a .relkey second factor
Add `--key-file <path>` to `relicario init` as a mutually exclusive alternative to `--image`/`--output`. When given, a 32-byte secret is generated with OsRng, armored via `keyfile_encode`, written to the supplied path (gitignored, never committed), and `params.json` records `"second_factor": "keyfile"`. The `--image` arg is now Option<PathBuf>; existing image-vault callers are unchanged. `ParamsFile::for_new_vault` now takes the second-factor variant as an explicit argument. Tests: un-ignore init_keyfile_then_unlock_keyfile_round_trips (full round-trip), strengthen its assertion to check for distinctive username "octocat", and add init_keyfile_writes_relkey_and_keyfile_params (armor, params parse, gitignore). Full workspace green (0 failures), clippy clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01McMF5pUJbCMricmFEnf2sG
This commit is contained in:
@@ -148,7 +148,7 @@ pub(crate) struct ParamsKdf {
|
||||
}
|
||||
|
||||
impl ParamsFile {
|
||||
pub fn for_new_vault(params: &KdfParams) -> Self {
|
||||
pub fn for_new_vault(params: &KdfParams, second_factor: SecondFactor) -> Self {
|
||||
Self {
|
||||
format_version: 2,
|
||||
kdf: ParamsKdf {
|
||||
@@ -159,7 +159,7 @@ impl ParamsFile {
|
||||
},
|
||||
aead: "xchacha20poly1305".into(),
|
||||
salt_path: ".relicario/salt".into(),
|
||||
second_factor: SecondFactor::Image,
|
||||
second_factor,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ mod tests {
|
||||
#[test]
|
||||
fn for_new_vault_produces_expected_shape() {
|
||||
let params = KdfParams { argon2_m: 65536, argon2_t: 3, argon2_p: 4 };
|
||||
let pf = ParamsFile::for_new_vault(¶ms);
|
||||
let pf = ParamsFile::for_new_vault(¶ms, relicario_core::SecondFactor::Image);
|
||||
let v = serde_json::to_value(&pf).expect("to_value");
|
||||
assert_eq!(v["format_version"], 2);
|
||||
assert_eq!(v["kdf"]["algorithm"], "argon2id-v0x13");
|
||||
|
||||
Reference in New Issue
Block a user