Basic project structure and error handling

This commit is contained in:
oupson 2022-05-18 20:38:41 +02:00
parent 13c0ed814c
commit c748297aa2
11 changed files with 190 additions and 244 deletions

258
Cargo.lock generated
View File

@ -50,9 +50,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.53" version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]] [[package]]
name = "atty" name = "atty"
@ -107,18 +107,6 @@ dependencies = [
"generic-array", "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]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
@ -185,9 +173,9 @@ dependencies = [
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -243,9 +231,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.4" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -285,18 +273,18 @@ dependencies = [
[[package]] [[package]]
name = "hkdf" name = "hkdf"
version = "0.12.2" version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "158bc31e00a68e380286904cc598715f861f2b0ccf7aa6fe20c6d0c49ca5d0f6" checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"
dependencies = [ dependencies = [
"hmac", "hmac",
] ]
[[package]] [[package]]
name = "hmac" name = "hmac"
version = "0.12.0" version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddca131f3e7f2ce2df364b57949a9d47915cfbd35e46cfee355ccebbf794d6a2" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [ dependencies = [
"digest", "digest",
] ]
@ -323,18 +311,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "js-sys"
version = "0.3.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04"
dependencies = [
"wasm-bindgen",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
@ -344,9 +323,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.117" version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]] [[package]]
name = "log" name = "log"
@ -357,12 +336,6 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "once_cell"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
version = "0.3.0" version = "0.3.0"
@ -388,9 +361,9 @@ dependencies = [
[[package]] [[package]]
name = "pbkdf2" name = "pbkdf2"
version = "0.10.0" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4628cc3cf953b82edcd3c1388c5715401420ce5524fedbab426bd5aba017434" checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7"
dependencies = [ dependencies = [
"digest", "digest",
] ]
@ -433,18 +406,18 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.36" version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
dependencies = [ dependencies = [
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.15" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -458,58 +431,39 @@ dependencies = [
"getrandom", "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]] [[package]]
name = "rustcryptfs" name = "rustcryptfs"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"aes 0.8.1",
"aes-gcm",
"anyhow", "anyhow",
"base64",
"cipher 0.4.3",
"clap", "clap",
"eme-mode",
"hkdf",
"log", "log",
"rustls", "rustcryptfs-lib",
"scrypt",
"serde", "serde",
"serde_json", "serde_json",
"sha2",
] ]
[[package]] [[package]]
name = "rustls" name = "rustcryptfs-lib"
version = "0.20.2" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84"
dependencies = [ dependencies = [
"log", "aes 0.8.1",
"ring", "aes-gcm",
"sct", "base64",
"webpki", "cipher 0.4.3",
"eme-mode",
"hkdf",
"scrypt",
"serde",
"sha2",
"thiserror",
] ]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]] [[package]]
name = "salsa20" name = "salsa20"
@ -533,30 +487,20 @@ dependencies = [
"sha2", "sha2",
] ]
[[package]]
name = "sct"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring",
"untrusted",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.136" version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.136" version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -565,9 +509,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.78" version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -585,12 +529,6 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.10.0"
@ -605,13 +543,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.86" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
@ -629,6 +567,26 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" 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]] [[package]]
name = "typenum" name = "typenum"
version = "1.15.0" version = "1.15.0"
@ -636,10 +594,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-ident"
version = "0.2.2" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
[[package]] [[package]]
name = "universal-hash" name = "universal-hash"
@ -651,12 +609,6 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 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]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

View File

@ -1,22 +1,5 @@
[package] [workspace]
name = "rustcryptfs" members = [
version = "0.0.1" "rustcryptfs",
edition = "2021" "rustcryptfs-lib"
]
# 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"

View File

@ -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"

View File

@ -7,8 +7,10 @@ use aes_gcm::{
}; };
use hkdf::Hkdf; use hkdf::Hkdf;
use crate::error::{Result, FilenameDecryptError, ScryptError};
#[derive(serde::Deserialize, Debug, PartialEq, Eq, Hash)] #[derive(serde::Deserialize, Debug, PartialEq, Eq, Hash)]
pub(crate) enum FeatureFlag { pub enum FeatureFlag {
/// FlagPlaintextNames indicates that filenames are unencrypted. /// FlagPlaintextNames indicates that filenames are unencrypted.
PlaintextNames, PlaintextNames,
/// FlagDirIV indicates that a per-directory IV file is used. /// FlagDirIV indicates that a per-directory IV file is used.
@ -45,7 +47,7 @@ pub(crate) enum FeatureFlag {
} }
#[derive(serde::Deserialize, Debug)] #[derive(serde::Deserialize, Debug)]
pub(crate) struct CryptConf { pub struct CryptConf {
#[serde(rename = "Creator")] #[serde(rename = "Creator")]
creator: String, creator: String,
#[serde(rename = "EncryptedKey")] #[serde(rename = "EncryptedKey")]
@ -59,7 +61,7 @@ pub(crate) struct CryptConf {
} }
impl CryptConf { impl CryptConf {
pub(crate) fn get_master_key(&self, password: &[u8]) -> anyhow::Result<Vec<u8>> { pub fn get_master_key(&self, password: &[u8]) -> Result<Vec<u8>> {
let block = base64::decode(&self.encrypted_key)?; let block = base64::decode(&self.encrypted_key)?;
let key = self.scrypt_object.get_hkdf_key(password)?; let key = self.scrypt_object.get_hkdf_key(password)?;
@ -76,19 +78,18 @@ impl CryptConf {
&[0u8, 0, 0, 0, 0, 0, 0, 0], &[0u8, 0, 0, 0, 0, 0, 0, 0],
&mut buf, &mut buf,
GenericArray::from_slice(tag), GenericArray::from_slice(tag),
) )?;
.unwrap();
Ok(buf) 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) self.feature_flags.contains(flag)
} }
} }
#[derive(serde::Deserialize, Debug)] #[derive(serde::Deserialize, Debug)]
pub(crate) struct ScryptObject { pub struct ScryptObject {
#[serde(rename = "Salt")] #[serde(rename = "Salt")]
salt: String, salt: String,
#[serde(rename = "N")] #[serde(rename = "N")]
@ -102,22 +103,20 @@ pub(crate) struct ScryptObject {
} }
impl ScryptObject { impl ScryptObject {
pub(crate) fn get_hkdf_key(&self, password: &[u8]) -> anyhow::Result<Vec<u8>> { pub fn get_hkdf_key(&self, password: &[u8]) -> std::result::Result<Vec<u8>, FilenameDecryptError> {
let mut key = [0u8; 32]; 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( scrypt::scrypt(
password, password,
&base64::decode(&self.salt).unwrap(), &base64::decode(&self.salt).unwrap(),
&params, &params,
&mut key, &mut key,
)?; ).map_err(|e| ScryptError::from(e))?;
let hdkf = Hkdf::<sha2::Sha256>::new(None, &key); let hdkf = Hkdf::<sha2::Sha256>::new(None, &key);
hdkf.expand(b"AES-GCM file content encryption", &mut key)?;
hdkf.expand(b"AES-GCM file content encryption", &mut key)
.unwrap();
Ok(key.to_vec()) Ok(key.to_vec())
} }

View File

@ -2,6 +2,8 @@ use aes_gcm::{aead::generic_array::GenericArray, aes::Aes256, AeadInPlace, AesGc
use cipher::consts::{U16, U32}; use cipher::consts::{U16, U32};
use hkdf::Hkdf; use hkdf::Hkdf;
use crate::error::{Result, DecryptError};
type Aes256Gcm = AesGcm<Aes256, U16>; type Aes256Gcm = AesGcm<Aes256, U16>;
pub struct ContentEnc { pub struct ContentEnc {
@ -27,7 +29,7 @@ impl ContentEnc {
block: &[u8], block: &[u8],
block_number: u64, block_number: u64,
file_id: Option<&[u8]>, file_id: Option<&[u8]>,
) -> anyhow::Result<Vec<u8>> { ) -> Result<Vec<u8>> {
// TODO NOT BOX // TODO NOT BOX
if block.len() == 0 { if block.len() == 0 {
return Ok(block.into()); return Ok(block.into());
@ -38,7 +40,7 @@ impl ContentEnc {
} }
if block.len() < self.iv_len { 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]; let nonce = &block[..self.iv_len];
@ -46,7 +48,7 @@ impl ContentEnc {
let ciphertext = &block[self.iv_len..block.len() - self.iv_len]; let ciphertext = &block[self.iv_len..block.len() - self.iv_len];
if nonce.iter().all(|f| *f == 0) { 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); let mut buf = Vec::from(ciphertext);
@ -63,8 +65,7 @@ impl ContentEnc {
&aad, &aad,
&mut buf, &mut buf,
GenericArray::from_slice(tag), GenericArray::from_slice(tag),
) )?;
.unwrap();
return Ok(buf.to_vec()); return Ok(buf.to_vec());
} }

View File

@ -0,0 +1,49 @@
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[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<aes_gcm::Error> 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),
}

View File

@ -3,15 +3,17 @@ use cipher::{block_padding::Pkcs7, KeyIvInit};
use eme_mode::DynamicEme; use eme_mode::DynamicEme;
use hkdf::Hkdf; use hkdf::Hkdf;
use crate::error::FilenameDecryptError;
pub struct FilenameDecoder { pub struct FilenameDecoder {
filename_key: [u8; 32], filename_key: [u8; 32],
} }
impl FilenameDecoder { impl FilenameDecoder {
pub fn new(master_key: &[u8]) -> anyhow::Result<Self> { pub fn new(master_key: &[u8]) -> Result<Self, FilenameDecryptError> {
let mut key = [0u8; 32]; let mut key = [0u8; 32];
let hdkf = Hkdf::<sha2::Sha256>::new(None, &master_key); let hdkf = Hkdf::<sha2::Sha256>::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 }) 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> { pub fn get_decoder_for_dir<'a, 'b>(&'a self, iv: &'b [u8]) -> DirFilenameDecoder<'a, 'b> {
DirFilenameDecoder { DirFilenameDecoder {
filename_key: &self.filename_key, filename_key: &self.filename_key,
iv: iv, iv,
} }
} }
} }
@ -30,11 +32,14 @@ pub struct DirFilenameDecoder<'a, 'b> {
} }
impl<'a, 'b> DirFilenameDecoder<'a, 'b> { impl<'a, 'b> DirFilenameDecoder<'a, 'b> {
pub fn decode_filename(&self, name: &str) -> anyhow::Result<String> { pub fn decode_filename(&self, name: &str) -> Result<String, FilenameDecryptError> {
let cipher = DynamicEme::<Aes256>::new_from_slices(self.filename_key, self.iv)?; let cipher = DynamicEme::<Aes256>::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 mut filename = base64::decode_config(name, base64::URL_SAFE)?;
let filename_decoded = cipher.decrypt_padded_mut::<Pkcs7>(&mut filename).unwrap(); let filename_decoded = cipher
.decrypt_padded_mut::<Pkcs7>(&mut filename)
.map_err(|_| FilenameDecryptError::DecryptError())?;
Ok(String::from_utf8_lossy(filename_decoded).to_string()) Ok(String::from_utf8_lossy(filename_decoded).to_string())
} }

View File

@ -0,0 +1,4 @@
pub mod config;
pub mod content_enc;
pub mod filename;
pub mod error;

14
rustcryptfs/Cargo.toml Normal file
View File

@ -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" }

View File

@ -6,16 +6,11 @@ use std::{
use anyhow::Context; use anyhow::Context;
use clap::Parser; use clap::Parser;
use filename::FilenameDecoder;
use crate::content_enc::ContentEnc;
use args::{DecryptCommand, LsCommand}; use args::{DecryptCommand, LsCommand};
use rustcryptfs_lib::{config::{self, CryptConf}, filename::FilenameDecoder, content_enc::ContentEnc};
mod args; mod args;
mod config;
mod content_enc;
mod filename;
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
let args = args::Args::parse(); let args = args::Args::parse();
@ -37,10 +32,10 @@ fn ls(c: &LsCommand) -> anyhow::Result<()> {
let content = fs::read_to_string(config_path)?; 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")?; 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)?; let filename_decoder = FilenameDecoder::new(&master_key)?;