From 77d3037e983cb0c5c0a2f908a72606e50a6dfab6 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Fri, 12 Jun 2026 22:54:07 +0200 Subject: [PATCH] docs: document read_key_file's missing permission check read_key_file moved from main.rs into the library without a doc comment. The world-readable key-file warning lives only in the CLI wrapper (read_key_file_cli), so a library user calling read_key_file directly silently loses that security check without anything telling them so. Spell out the contract: exact-32-byte parsing, and no permission checking - callers must do their own. Also document normalize_passphrase (why NFC normalization happens) since it became public API in the same move. Comment-only change, no code touched. --- src/secrets.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/secrets.rs b/src/secrets.rs index 16da66a..9b5e22b 100644 --- a/src/secrets.rs +++ b/src/secrets.rs @@ -129,6 +129,12 @@ impl PartialEq for SecretVec { } } +/// Reads a raw 32-byte key from `path`, rejecting files that are not exactly +/// 32 bytes long (a likely trailing newline is called out in the error). +/// +/// Performs **no permission checking** on the file. Library callers who care +/// whether the key file is readable by others must check themselves; the fcry +/// CLI does this and prints a warning (see `read_key_file_cli` in the binary). pub fn read_key_file(path: &Path) -> Result { let mut file = File::open(path)?; let mut buf = Zeroizing::new([0u8; 33]); @@ -165,6 +171,9 @@ pub fn read_key_file(path: &Path) -> Result { Ok(key) } +/// Normalizes a passphrase to Unicode NFC so the same visual passphrase +/// always derives the same key regardless of how the platform or input +/// method composed it. Fails if the bytes are not valid UTF-8. pub fn normalize_passphrase(pw: SecretVec) -> Result { let normalized = pw.with_slice(|bytes| { let s = std::str::from_utf8(bytes).map_err(|_| {