From c748297aa20fdf6d3b53fc6bc3776cb7a627c845 Mon Sep 17 00:00:00 2001 From: oupson Date: Wed, 18 May 2022 20:38:41 +0200 Subject: [PATCH] Basic project structure and error handling --- Cargo.lock | 258 ++++++-------------- Cargo.toml | 27 +- rustcryptfs-lib/Cargo.toml | 18 ++ {src => rustcryptfs-lib/src}/config.rs | 25 +- {src => rustcryptfs-lib/src}/content_enc.rs | 11 +- rustcryptfs-lib/src/error.rs | 49 ++++ {src => rustcryptfs-lib/src}/filename.rs | 17 +- rustcryptfs-lib/src/lib.rs | 4 + rustcryptfs/Cargo.toml | 14 ++ {src => rustcryptfs/src}/args.rs | 0 {src => rustcryptfs/src}/main.rs | 11 +- 11 files changed, 190 insertions(+), 244 deletions(-) create mode 100644 rustcryptfs-lib/Cargo.toml rename {src => rustcryptfs-lib/src}/config.rs (87%) rename {src => rustcryptfs-lib/src}/content_enc.rs (89%) create mode 100644 rustcryptfs-lib/src/error.rs rename {src => rustcryptfs-lib/src}/filename.rs (62%) create mode 100644 rustcryptfs-lib/src/lib.rs create mode 100644 rustcryptfs/Cargo.toml rename {src => rustcryptfs/src}/args.rs (100%) rename {src => rustcryptfs/src}/main.rs (94%) diff --git a/Cargo.lock b/Cargo.lock index 4067a94..643f169 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.53" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" [[package]] name = "atty" @@ -107,18 +107,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bumpalo" -version = "3.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" - -[[package]] -name = "cc" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" - [[package]] name = "cfg-if" version = "1.0.0" @@ -185,9 +173,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] @@ -243,9 +231,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if", "libc", @@ -285,18 +273,18 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "158bc31e00a68e380286904cc598715f861f2b0ccf7aa6fe20c6d0c49ca5d0f6" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddca131f3e7f2ce2df364b57949a9d47915cfbd35e46cfee355ccebbf794d6a2" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ "digest", ] @@ -323,18 +311,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "js-sys" -version = "0.3.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" -dependencies = [ - "wasm-bindgen", -] +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "lazy_static" @@ -344,9 +323,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.117" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "log" @@ -357,12 +336,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "once_cell" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -388,9 +361,9 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4628cc3cf953b82edcd3c1388c5715401420ce5524fedbab426bd5aba017434" +checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" dependencies = [ "digest", ] @@ -433,18 +406,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -458,58 +431,39 @@ dependencies = [ "getrandom", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - [[package]] name = "rustcryptfs" version = "0.0.1" dependencies = [ - "aes 0.8.1", - "aes-gcm", "anyhow", - "base64", - "cipher 0.4.3", "clap", - "eme-mode", - "hkdf", "log", - "rustls", - "scrypt", + "rustcryptfs-lib", "serde", "serde_json", - "sha2", ] [[package]] -name = "rustls" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84" +name = "rustcryptfs-lib" +version = "0.1.0" dependencies = [ - "log", - "ring", - "sct", - "webpki", + "aes 0.8.1", + "aes-gcm", + "base64", + "cipher 0.4.3", + "eme-mode", + "hkdf", + "scrypt", + "serde", + "sha2", + "thiserror", ] [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "salsa20" @@ -533,30 +487,20 @@ dependencies = [ "sha2", ] -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "serde" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -565,9 +509,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.78" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ "itoa", "ryu", @@ -585,12 +529,6 @@ dependencies = [ "digest", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "strsim" version = "0.10.0" @@ -605,13 +543,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.86" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -629,6 +567,26 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "typenum" version = "1.15.0" @@ -636,10 +594,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" [[package]] name = "universal-hash" @@ -651,12 +609,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "version_check" version = "0.9.4" @@ -669,80 +621,6 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" -[[package]] -name = "wasm-bindgen" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" - -[[package]] -name = "web-sys" -version = "0.3.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 3839475..b17d160 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,5 @@ -[package] -name = "rustcryptfs" -version = "0.0.1" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.53" -base64 = "0.13.0" -rustls = "0.20.2" -scrypt = "0.8" -serde = { version = "1.0.136", features = ["derive"] } -serde_json = "1.0.78" -aes= "0.8.1" -aes-gcm = "0.9.4" -hkdf = "0.12.2" -sha2 = "0.10.2" -cipher = "0.4.3" -clap = { version = "3.1.18", features = ["derive"] } -log = "0.4.17" -eme-mode = "0.3.1" \ No newline at end of file +[workspace] +members = [ + "rustcryptfs", + "rustcryptfs-lib" +] diff --git a/rustcryptfs-lib/Cargo.toml b/rustcryptfs-lib/Cargo.toml new file mode 100644 index 0000000..3f9816e --- /dev/null +++ b/rustcryptfs-lib/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "rustcryptfs-lib" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +base64 = "0.13" +scrypt = "0.8" +serde = { version = "1.0", features = ["derive"] } +aes= "0.8" +aes-gcm = "0.9" +hkdf = { version = "0.12", features = ["std"] } +sha2 = "0.10" +cipher = "0.4" +eme-mode = "0.3" +thiserror = "1.0" diff --git a/src/config.rs b/rustcryptfs-lib/src/config.rs similarity index 87% rename from src/config.rs rename to rustcryptfs-lib/src/config.rs index e9a8a05..c4ccffd 100644 --- a/src/config.rs +++ b/rustcryptfs-lib/src/config.rs @@ -7,8 +7,10 @@ use aes_gcm::{ }; use hkdf::Hkdf; +use crate::error::{Result, FilenameDecryptError, ScryptError}; + #[derive(serde::Deserialize, Debug, PartialEq, Eq, Hash)] -pub(crate) enum FeatureFlag { +pub enum FeatureFlag { /// FlagPlaintextNames indicates that filenames are unencrypted. PlaintextNames, /// FlagDirIV indicates that a per-directory IV file is used. @@ -45,7 +47,7 @@ pub(crate) enum FeatureFlag { } #[derive(serde::Deserialize, Debug)] -pub(crate) struct CryptConf { +pub struct CryptConf { #[serde(rename = "Creator")] creator: String, #[serde(rename = "EncryptedKey")] @@ -59,7 +61,7 @@ pub(crate) struct CryptConf { } impl CryptConf { - pub(crate) fn get_master_key(&self, password: &[u8]) -> anyhow::Result> { + pub fn get_master_key(&self, password: &[u8]) -> Result> { let block = base64::decode(&self.encrypted_key)?; let key = self.scrypt_object.get_hkdf_key(password)?; @@ -76,19 +78,18 @@ impl CryptConf { &[0u8, 0, 0, 0, 0, 0, 0, 0], &mut buf, GenericArray::from_slice(tag), - ) - .unwrap(); + )?; Ok(buf) } - pub(crate) fn have_feature_flag(&self, flag: &FeatureFlag) -> bool { + pub fn have_feature_flag(&self, flag: &FeatureFlag) -> bool { self.feature_flags.contains(flag) } } #[derive(serde::Deserialize, Debug)] -pub(crate) struct ScryptObject { +pub struct ScryptObject { #[serde(rename = "Salt")] salt: String, #[serde(rename = "N")] @@ -102,22 +103,20 @@ pub(crate) struct ScryptObject { } impl ScryptObject { - pub(crate) fn get_hkdf_key(&self, password: &[u8]) -> anyhow::Result> { + pub fn get_hkdf_key(&self, password: &[u8]) -> std::result::Result, FilenameDecryptError> { let mut key = [0u8; 32]; - let params = scrypt::Params::new((self.n as f64).log2() as u8, self.r, self.p)?; + let params = scrypt::Params::new((self.n as f64).log2() as u8, self.r, self.p).map_err(|e| ScryptError::from(e))?; scrypt::scrypt( password, &base64::decode(&self.salt).unwrap(), ¶ms, &mut key, - )?; + ).map_err(|e| ScryptError::from(e))?; let hdkf = Hkdf::::new(None, &key); - - hdkf.expand(b"AES-GCM file content encryption", &mut key) - .unwrap(); + hdkf.expand(b"AES-GCM file content encryption", &mut key)?; Ok(key.to_vec()) } diff --git a/src/content_enc.rs b/rustcryptfs-lib/src/content_enc.rs similarity index 89% rename from src/content_enc.rs rename to rustcryptfs-lib/src/content_enc.rs index 0e2aaff..ed94ff3 100644 --- a/src/content_enc.rs +++ b/rustcryptfs-lib/src/content_enc.rs @@ -2,6 +2,8 @@ use aes_gcm::{aead::generic_array::GenericArray, aes::Aes256, AeadInPlace, AesGc use cipher::consts::{U16, U32}; use hkdf::Hkdf; +use crate::error::{Result, DecryptError}; + type Aes256Gcm = AesGcm; pub struct ContentEnc { @@ -27,7 +29,7 @@ impl ContentEnc { block: &[u8], block_number: u64, file_id: Option<&[u8]>, - ) -> anyhow::Result> { + ) -> Result> { // TODO NOT BOX if block.len() == 0 { return Ok(block.into()); @@ -38,7 +40,7 @@ impl ContentEnc { } if block.len() < self.iv_len { - return Err(anyhow::Error::msg("Block is too short")); + return Err(DecryptError::BlockTooShort().into()); } let nonce = &block[..self.iv_len]; @@ -46,7 +48,7 @@ impl ContentEnc { let ciphertext = &block[self.iv_len..block.len() - self.iv_len]; if nonce.iter().all(|f| *f == 0) { - return Err(anyhow::Error::msg("all-zero nonce")); + return Err(DecryptError::AllZeroNonce().into()); } let mut buf = Vec::from(ciphertext); @@ -63,8 +65,7 @@ impl ContentEnc { &aad, &mut buf, GenericArray::from_slice(tag), - ) - .unwrap(); + )?; return Ok(buf.to_vec()); } diff --git a/rustcryptfs-lib/src/error.rs b/rustcryptfs-lib/src/error.rs new file mode 100644 index 0000000..582dcec --- /dev/null +++ b/rustcryptfs-lib/src/error.rs @@ -0,0 +1,49 @@ +use thiserror::Error; + +pub type Result = std::result::Result; + +#[derive(Debug, Error)] +pub enum Error { + #[error("Failed to decrypt content")] + ContentDecryptError(), + #[error("Failed to decrypt filename")] + FilenameDecryptError(#[from] FilenameDecryptError), + #[error("Failed to decode base64")] + Base64Error(#[from] base64::DecodeError), + #[error(transparent)] + DecodeError(#[from] DecryptError), +} + +impl From for Error { + fn from(_: aes_gcm::Error) -> Self { + Self::ContentDecryptError() + } +} + +#[derive(Debug, Error)] +pub enum DecryptError { + #[error("Block is too short")] + BlockTooShort(), + #[error("all-zero nonce")] + AllZeroNonce(), +} + +#[derive(Debug, Error)] +pub enum FilenameDecryptError { + #[error(transparent)] + ScryptError(#[from] ScryptError), + #[error("Failed to decode base64")] + Base64Error(#[from] base64::DecodeError), + #[error(transparent)] + HdkfError(#[from] hkdf::InvalidLength), + #[error("Failed to decrypt filename")] + DecryptError(), +} + +#[derive(Debug, Error)] +pub enum ScryptError { + #[error(transparent)] + InvalidParams(#[from] scrypt::errors::InvalidParams), + #[error(transparent)] + InvalidOutputLen(#[from] scrypt::errors::InvalidOutputLen), +} diff --git a/src/filename.rs b/rustcryptfs-lib/src/filename.rs similarity index 62% rename from src/filename.rs rename to rustcryptfs-lib/src/filename.rs index 0f11798..97dbfac 100644 --- a/src/filename.rs +++ b/rustcryptfs-lib/src/filename.rs @@ -3,15 +3,17 @@ use cipher::{block_padding::Pkcs7, KeyIvInit}; use eme_mode::DynamicEme; use hkdf::Hkdf; +use crate::error::FilenameDecryptError; + pub struct FilenameDecoder { filename_key: [u8; 32], } impl FilenameDecoder { - pub fn new(master_key: &[u8]) -> anyhow::Result { + pub fn new(master_key: &[u8]) -> Result { let mut key = [0u8; 32]; let hdkf = Hkdf::::new(None, &master_key); - hdkf.expand(b"EME filename encryption", &mut key).unwrap(); + hdkf.expand(b"EME filename encryption", &mut key)?; Ok(Self { filename_key: key }) } @@ -19,7 +21,7 @@ impl FilenameDecoder { pub fn get_decoder_for_dir<'a, 'b>(&'a self, iv: &'b [u8]) -> DirFilenameDecoder<'a, 'b> { DirFilenameDecoder { filename_key: &self.filename_key, - iv: iv, + iv, } } } @@ -30,11 +32,14 @@ pub struct DirFilenameDecoder<'a, 'b> { } impl<'a, 'b> DirFilenameDecoder<'a, 'b> { - pub fn decode_filename(&self, name: &str) -> anyhow::Result { - let cipher = DynamicEme::::new_from_slices(self.filename_key, self.iv)?; + pub fn decode_filename(&self, name: &str) -> Result { + let cipher = DynamicEme::::new_from_slices(self.filename_key, self.iv) + .expect("failed to get filename cipher"); let mut filename = base64::decode_config(name, base64::URL_SAFE)?; - let filename_decoded = cipher.decrypt_padded_mut::(&mut filename).unwrap(); + let filename_decoded = cipher + .decrypt_padded_mut::(&mut filename) + .map_err(|_| FilenameDecryptError::DecryptError())?; Ok(String::from_utf8_lossy(filename_decoded).to_string()) } diff --git a/rustcryptfs-lib/src/lib.rs b/rustcryptfs-lib/src/lib.rs new file mode 100644 index 0000000..13f3b03 --- /dev/null +++ b/rustcryptfs-lib/src/lib.rs @@ -0,0 +1,4 @@ +pub mod config; +pub mod content_enc; +pub mod filename; +pub mod error; \ No newline at end of file diff --git a/rustcryptfs/Cargo.toml b/rustcryptfs/Cargo.toml new file mode 100644 index 0000000..9617d5e --- /dev/null +++ b/rustcryptfs/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "rustcryptfs" +version = "0.0.1" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.53" +serde = { version = "1.0.136", features = ["derive"] } +serde_json = "1.0.78" +clap = { version = "3.1.18", features = ["derive"] } +log = "0.4.17" +rustcryptfs-lib = { path = "../rustcryptfs-lib" } \ No newline at end of file diff --git a/src/args.rs b/rustcryptfs/src/args.rs similarity index 100% rename from src/args.rs rename to rustcryptfs/src/args.rs diff --git a/src/main.rs b/rustcryptfs/src/main.rs similarity index 94% rename from src/main.rs rename to rustcryptfs/src/main.rs index bab004e..edf2c36 100644 --- a/src/main.rs +++ b/rustcryptfs/src/main.rs @@ -6,16 +6,11 @@ use std::{ use anyhow::Context; use clap::Parser; -use filename::FilenameDecoder; - -use crate::content_enc::ContentEnc; use args::{DecryptCommand, LsCommand}; +use rustcryptfs_lib::{config::{self, CryptConf}, filename::FilenameDecoder, content_enc::ContentEnc}; mod args; -mod config; -mod content_enc; -mod filename; fn main() -> anyhow::Result<()> { let args = args::Args::parse(); @@ -37,10 +32,10 @@ fn ls(c: &LsCommand) -> anyhow::Result<()> { let content = fs::read_to_string(config_path)?; - let conf: config::CryptConf = + let conf: CryptConf = serde_json::from_str(&content).context("Failed to decode configuration")?; - let master_key = conf.get_master_key(c.password.as_ref().unwrap().as_bytes())?; + let master_key = conf.get_master_key(c.password.as_ref().unwrap().as_bytes()).context("Failed to get master key")?; let filename_decoder = FilenameDecoder::new(&master_key)?;