feat: split crate into library and thin CLI binary

The crypto engine was only reachable through the fcry binary; embedding
it in another Rust project meant shelling out to the CLI. Restructure
the crate so the binary sits on top of a proper library API.

- Add src/lib.rs exposing encrypt/decrypt/decrypt_range/derive_key, the
  header and policy types, and the secret-handling primitives.
- Replace the positional-argument wrapper ladder
  (encrypt_with_output_options, decrypt_with_argon_cap, ...) with
  options structs: EncryptOptions, DecryptOptions, DecryptRangeOptions
  and HeaderReadOptions. OutSinkOptions becomes the public
  OutputOptions and no longer carries the input path; the input is now
  an explicit parameter to OutSink::open_with_options so the
  same-file-aliasing guard's inputs are visible at each call site.
- File parameters take Option<PathBuf>/&Path instead of AsRef<str>, so
  non-UTF-8 paths work.
- FcryError implements Display and std::error::Error so it composes
  with anyhow/thiserror-style error handling in downstream crates.
- Move read_key_file and normalize_passphrase from main.rs into
  secrets.rs so library users get the same strict 32-byte key-file
  parsing and NFC passphrase normalization. The world-readable
  key-file warning stays in the CLI wrapper (read_key_file_cli).
- Drop now-unneeded #[allow(dead_code)] markers; ReadInfoChunk::Normal
  loses its unused byte-count payload.
- Add rustfmt.toml (StdExternalCrate grouping, crate-granularity
  imports) and reformat imports accordingly.
- Add tests/library_api.rs covering a file round-trip and a range
  decrypt through the public API with a raw key.

User-visible change: CLI behavior is unchanged except error output,
which is now human-readable Display text ("Error: wrong key or
passphrase") instead of the Rust Debug representation.

Test plan: cargo clippy (default, --tests, --benches) is clean;
cargo +nightly fmt produces no diff; cargo test passes 43 tests
including the new library_api integration tests.
This commit is contained in:
2026-06-12 22:49:23 +02:00
parent f44cfc6190
commit 2f16e735c3
13 changed files with 533 additions and 356 deletions
+64
View File
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: MIT-0
mod crypto;
mod error;
mod header;
mod pipeline;
mod policy;
mod reader;
mod secrets;
mod utils;
pub use crate::{
crypto::{
DecryptOptions,
DecryptRangeOptions,
EncryptOptions,
decrypt,
decrypt_range,
derive_key,
encrypt,
},
error::FcryError,
header::{
ARGON2_SALT_LEN,
AlgId,
FLAG_KEY_COMMITTED,
FLAG_LENGTH_COMMITTED,
Header,
HeaderReadOptions,
KEY_COMMITMENT_LEN,
KdfParams,
NONCE_PREFIX_LEN,
TAG_LEN,
VERSION_CURRENT,
},
policy::{
ArgonDecryptCap,
DEFAULT_ARGON_DECRYPT_CAP_MIB,
DEFAULT_ARGON_MEMORY_MIB,
DEFAULT_ARGON_PARALLELISM,
MAX_ARGON_PARALLELISM,
MAX_ARGON_PASSES,
MAX_CHUNK_SIZE,
MAX_WORKER_THREADS,
MIN_ARGON_MEMORY_MIB,
MIN_ARGON_PASSES,
MIN_PASSPHRASE_BYTES,
architecture_argon_cap_mib,
default_argon_decrypt_cap_mib,
normalize_worker_threads,
resolve_argon_decrypt_cap,
validate_new_argon_params,
validate_new_passphrase,
},
secrets::{
MAX_PASSPHRASE_LEN,
SecretBytes32,
SecretVec,
normalize_passphrase,
read_key_file,
read_passphrase_tty,
},
utils::{DEFAULT_CHUNK_SIZE, OutputOptions},
};