Files
relicario/crates/relicario-core/src/lib.rs
adlee-was-taken 6a1c6d5875 fix(core,cli): harden backup-restore tar unpack against path traversal (audit S2)
cmd_backup_restore previously called tar::Archive::unpack with default
settings, allowing malicious .relbak archives to escape the target
directory via .. entries, absolute paths, or symlinks. No size cap
meant tar bombs could exhaust disk space.

Replaced with relicario_core::safe_unpack_git_archive which:
- Rejects .. (ParentDir), absolute (RootDir), and drive-prefix
  (Prefix) components with "path traversal blocked" error.
- Rejects symlinks and hardlinks outright.
- Checks declared header size before reading body; rejects entries or
  cumulative totals exceeding the caller's cap.
- Returns (relative-path, bytes) pairs; the CLI re-checks
  dest.starts_with(git_dir) after OS-level path resolution.
- CLI cap: min(100 × compressed size, 1 GiB).

Acceptance: 5 unit tests in relicario-core (traversal, absolute path,
symlink, size bomb, happy path); existing CLI backup roundtrip tests
remain green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 17:16:11 -04:00

92 lines
3.4 KiB
Rust

//! # relicario-core
//!
//! Platform-agnostic core library for the Relicario password manager.
//!
//! This crate is intentionally **bytes-in/bytes-out** -- it performs no filesystem
//! access, no network I/O, and no git operations. All inputs arrive as byte slices
//! or typed structs, and all outputs are returned as byte vectors or typed structs.
//! This design makes the crate portable to WASM, Android (via JNI/UniFFI), and iOS
//! without any conditional compilation or platform shims.
//!
//! ## Modules
//!
//! - [`error`] — The unified error type ([`RelicarioError`]).
//! - [`crypto`] — Argon2id KDF (length-prefixed inputs, Zeroizing output) and
//! XChaCha20-Poly1305 AEAD with VERSION_BYTE 0x02.
//! - [`ids`] — `ItemId`, `FieldId`, and content-addressed `AttachmentId`.
//! - [`time`] — unix-seconds + `MonthYear` for card expiries.
//! - [`item_types`] — Per-type cores (`LoginCore`, `SecureNoteCore`, etc.) and the
//! `ItemCore`/`ItemType` enums.
//! - [`item`] — `Item` envelope, `Field`, `FieldKind`, `FieldValue`, `Section`,
//! `FieldHistoryEntry`.
//! - [`attachment`] — `AttachmentRef`, `AttachmentSummary`, encrypt/decrypt helpers.
//! - [`manifest`] — Browse-without-decrypt index (schema_version 2).
//! - [`settings`] — Vault-level retention, generator defaults, attachment caps.
//! - [`generators`] — CSPRNG password + BIP39 passphrase generators; zxcvbn
//! strength gate.
//! - [`vault`] — Typed encrypt/decrypt wrappers (Item, Manifest, VaultSettings).
//! - [`imgsecret`] — DCT-based steganography for the second auth factor.
//!
//! ## Crypto pipeline
//!
//! ```text
//! passphrase (UTF-8 bytes) || image_secret (32 bytes from reference JPEG)
//! -> Argon2id(salt=vault_salt, m=64MiB, t=3, p=4)
//! -> master_key (32 bytes)
//! -> XChaCha20-Poly1305(nonce=random 24 bytes)
//! -> encrypted entry/manifest
//! ```
pub mod error;
pub use error::{RelicarioError, Result};
pub mod crypto;
pub use crypto::{decrypt, derive_master_key, encrypt, KdfParams, VERSION_BYTE};
pub mod ids;
pub use ids::{AttachmentId, FieldId, ItemId};
pub mod time;
pub use time::{now_unix, MonthYear};
pub mod item_types;
pub use item_types::{ItemCore, ItemType};
pub mod item;
pub use item::{Field, FieldHistoryEntry, FieldKind, FieldValue, Item, Section};
pub mod attachment;
pub use attachment::{decrypt_attachment, encrypt_attachment, AttachmentRef, AttachmentSummary, EncryptedAttachment};
pub mod manifest;
pub use manifest::{Manifest, ManifestEntry, MANIFEST_SCHEMA_VERSION};
pub mod settings;
pub use settings::{
AttachmentCaps, Capitalization, CharClasses, GeneratorRequest, HistoryRetention,
SymbolCharset, TrashRetention, VaultSettings,
};
pub mod generators;
pub use generators::{generate_passphrase, generate_password, rate_passphrase, validate_passphrase_strength, StrengthEstimate};
pub mod vault;
pub use vault::{
decrypt_item, decrypt_manifest, decrypt_settings,
encrypt_item, encrypt_manifest, encrypt_settings,
};
pub mod imgsecret;
pub mod backup;
pub use backup::{pack_backup, unpack_backup, BackupInput, BackupOutput, BackupItem, BackupAttachment};
pub mod import_lastpass;
pub use import_lastpass::{parse_lastpass_csv, ImportWarning};
pub mod device;
pub use device::{fingerprint, DeviceEntry, RevokedEntry, generate_keypair, sign, verify};
pub mod tar_safe;
pub use tar_safe::{safe_unpack_git_archive, DEFAULT_MAX_UNCOMPRESSED};