From 0e62e8d91c99fbe3525f286b16e921245733ad93 Mon Sep 17 00:00:00 2001 From: jake <77554505+brxken128@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:15:12 +0000 Subject: [PATCH] [ENG-312] Crypto details CLI tool (#500) * add untested crypto details tool * clean up output a little * clippy * update crate details and `clap` --- Cargo.lock | 200 ++++++++++++++++++++-- crates/crypto-cli/Cargo.toml | 15 ++ crates/crypto-cli/src/main.rs | 53 ++++++ crates/crypto/src/header/serialization.rs | 61 +++++++ 4 files changed, 317 insertions(+), 12 deletions(-) create mode 100644 crates/crypto-cli/Cargo.toml create mode 100644 crates/crypto-cli/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index edc85077c..fa7f4c99a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,9 +122,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "argon2" @@ -337,7 +337,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -830,11 +830,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "bitflags", - "clap_lex", + "clap_lex 0.2.4", "indexmap", "textwrap", ] +[[package]] +name = "clap" +version = "4.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex 0.3.0", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "clap_lex" version = "0.2.4" @@ -844,6 +872,15 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -1051,7 +1088,7 @@ dependencies = [ "atty", "cast", "ciborium", - "clap", + "clap 3.2.23", "criterion-plot", "itertools", "lazy_static", @@ -1136,6 +1173,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-cli" +version = "0.0.0" +dependencies = [ + "anyhow", + "clap 4.0.32", + "hex", + "sd-crypto", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -1570,6 +1617,27 @@ dependencies = [ "syn", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1672,7 +1740,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall 0.2.16", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -2276,6 +2344,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -2686,12 +2763,34 @@ dependencies = [ "syn", ] +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + [[package]] name = "ipnet" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + [[package]] name = "itertools" version = "0.10.5" @@ -2933,6 +3032,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "lock_api" version = "0.3.4" @@ -3273,7 +3378,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -3604,7 +3709,7 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -3711,7 +3816,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4a3100141f1733ea40b53381b0ae3117330735ef22309a190ac57b9576ea716" dependencies = [ "pathdiff", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -3936,7 +4041,7 @@ dependencies = [ "libc", "redox_syscall 0.2.16", "smallvec 1.10.0", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -5190,6 +5295,20 @@ dependencies = [ "semver 1.0.14", ] +[[package]] +name = "rustix" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + [[package]] name = "rustls" version = "0.20.6" @@ -5266,7 +5385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -7454,7 +7573,7 @@ dependencies = [ "cocoa", "objc", "raw-window-handle", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -7549,12 +7668,33 @@ dependencies = [ "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + [[package]] name = "windows-tokens" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.32.0" @@ -7585,6 +7725,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + [[package]] name = "windows_i686_gnu" version = "0.32.0" @@ -7615,6 +7761,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + [[package]] name = "windows_i686_msvc" version = "0.32.0" @@ -7645,6 +7797,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + [[package]] name = "windows_x86_64_gnu" version = "0.32.0" @@ -7675,6 +7833,18 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + [[package]] name = "windows_x86_64_msvc" version = "0.32.0" @@ -7705,6 +7875,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "winreg" version = "0.10.1" diff --git a/crates/crypto-cli/Cargo.toml b/crates/crypto-cli/Cargo.toml new file mode 100644 index 000000000..dc2dcc147 --- /dev/null +++ b/crates/crypto-cli/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "crypto-cli" +version = "0.0.0" +edition = "2021" +authors = ["Jake Robinson "] +description = "A CLI tool to view encrypted file details (for files encrypted with Spacedrive)" +rust-version = "1.64.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "4.0.32", features = ["derive"] } +sd-crypto = { path = "../crypto", features = ["serde"] } +anyhow = "1.0.68" +hex = "0.4.3" diff --git a/crates/crypto-cli/src/main.rs b/crates/crypto-cli/src/main.rs new file mode 100644 index 000000000..f6c1ff40f --- /dev/null +++ b/crates/crypto-cli/src/main.rs @@ -0,0 +1,53 @@ +use anyhow::{Context, Result}; +use clap::Parser; +use sd_crypto::header::file::FileHeader; +use std::{fs::File, path::PathBuf}; + +#[derive(Parser)] +struct Args { + #[arg(help = "the file path to get details for")] + path: PathBuf, +} + +fn main() -> Result<()> { + let args = Args::parse(); + + let mut reader = File::open(args.path).context("unable to open file")?; + let (header, aad) = FileHeader::deserialize(&mut reader)?; + print_details(&header, &aad)?; + + Ok(()) +} + +fn print_details(header: &FileHeader, aad: &[u8]) -> Result<()> { + println!("Header version: {}", header.version); + println!("Encryption algorithm: {}", header.algorithm); + println!("AAD (hex): {}", hex::encode(aad)); + header.keyslots.iter().enumerate().for_each(|(i, k)| { + println!("Keyslot {}:", i + 1); + println!(" Version: {}", k.version); + println!(" Algorithm: {}", k.algorithm); + println!(" Hashing algorithm: {}", k.hashing_algorithm); + println!(" Salt (hex): {}", hex::encode(k.salt)); + println!(" Master Key (hex, encrypted): {}", hex::encode(k.master_key)); + println!(" Master key nonce (hex): {}", hex::encode(k.nonce.clone())); + }); + + header.metadata.clone().iter().for_each(|m| { + println!("Metadata:"); + println!(" Version: {}", m.version); + println!(" Algorithm: {}", m.algorithm); + println!(" Encrypted size: {}", m.metadata.len()); + println!(" Nonce (hex): {}", hex::encode(m.metadata_nonce.clone())); + }); + + header.preview_media.clone().iter().for_each(|p| { + println!("Preview Media:"); + println!(" Version: {}", p.version); + println!(" Algorithm: {}", p.algorithm); + println!(" Encrypted size: {}", p.media.len()); + println!(" Nonce (hex): {}", hex::encode(p.media_nonce.clone())) + }); + + Ok(()) +} diff --git a/crates/crypto/src/header/serialization.rs b/crates/crypto/src/header/serialization.rs index f6e707b00..a4c49a34d 100644 --- a/crates/crypto/src/header/serialization.rs +++ b/crates/crypto/src/header/serialization.rs @@ -1,6 +1,8 @@ //! This module defines all of the serialization and deserialization rules for the header items //! //! It contains `byte -> enum` and `enum -> byte` conversions for everything that could be written to a header (except headers, keyslots, and other header items) +use std::fmt::Display; + use crate::{ crypto::stream::Algorithm, keys::hashing::{HashingAlgorithm, Params}, @@ -28,6 +30,14 @@ impl FileHeaderVersion { } } +impl Display for FileHeaderVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::V1 => write!(f, "V1"), + } + } +} + impl KeyslotVersion { #[must_use] pub const fn serialize(&self) -> [u8; 2] { @@ -44,6 +54,14 @@ impl KeyslotVersion { } } +impl Display for KeyslotVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::V1 => write!(f, "V1"), + } + } +} + impl PreviewMediaVersion { #[must_use] pub const fn serialize(&self) -> [u8; 2] { @@ -60,6 +78,14 @@ impl PreviewMediaVersion { } } +impl Display for PreviewMediaVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::V1 => write!(f, "V1"), + } + } +} + impl MetadataVersion { #[must_use] pub const fn serialize(&self) -> [u8; 2] { @@ -76,6 +102,14 @@ impl MetadataVersion { } } +impl Display for MetadataVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::V1 => write!(f, "V1"), + } + } +} + impl HashingAlgorithm { #[must_use] pub const fn serialize(&self) -> [u8; 2] { @@ -98,6 +132,24 @@ impl HashingAlgorithm { } } +impl Display for HashingAlgorithm { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::Argon2id(p) => write!(f, "Argon2id ({})", p), + } + } +} + +impl Display for Params { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::Standard => write!(f, "Standard"), + Self::Hardened => write!(f, "Hardened"), + Self::Paranoid => write!(f, "Paranoid"), + } + } +} + impl Algorithm { #[must_use] pub const fn serialize(&self) -> [u8; 2] { @@ -115,3 +167,12 @@ impl Algorithm { } } } + +impl Display for Algorithm { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::XChaCha20Poly1305 => write!(f, "XChaCha20-Poly1305"), + Self::Aes256Gcm => write!(f, "AES-256-GCM"), + } + } +}