Initial Commit

This commit is contained in:
oupson 2022-05-15 12:58:10 +02:00
commit 3b0fbb2e38
8 changed files with 1059 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
*.py
enc

743
Cargo.lock generated Normal file
View File

@ -0,0 +1,743 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aead"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877"
dependencies = [
"generic-array",
]
[[package]]
name = "aes"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
dependencies = [
"cfg-if",
"cipher 0.3.0",
"cpufeatures",
"opaque-debug",
]
[[package]]
name = "aes-gcm"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6"
dependencies = [
"aead",
"aes",
"cipher 0.3.0",
"ctr",
"ghash",
"subtle",
]
[[package]]
name = "anyhow"
version = "1.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "base64ct"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "block-buffer"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cipher"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
dependencies = [
"generic-array",
]
[[package]]
name = "cipher"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "clap"
version = "3.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"indexmap",
"lazy_static",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_derive"
version = "3.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "cpufeatures"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "ctr"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea"
dependencies = [
"cipher 0.3.0",
]
[[package]]
name = "digest"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]]
name = "generic-array"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "ghash"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99"
dependencies = [
"opaque-debug",
"polyval",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hkdf"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "158bc31e00a68e380286904cc598715f861f2b0ccf7aa6fe20c6d0c49ca5d0f6"
dependencies = [
"hmac",
]
[[package]]
name = "hmac"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddca131f3e7f2ce2df364b57949a9d47915cfbd35e46cfee355ccebbf794d6a2"
dependencies = [
"digest",
]
[[package]]
name = "indexmap"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"generic-array",
]
[[package]]
name = "itoa"
version = "1.0.1"
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",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "os_str_bytes"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "029d8d0b2f198229de29dca79676f2738ff952edf3fde542eb8bf94d8c21b435"
[[package]]
name = "password-hash"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8"
dependencies = [
"base64ct",
"rand_core",
"subtle",
]
[[package]]
name = "pbkdf2"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4628cc3cf953b82edcd3c1388c5715401420ce5524fedbab426bd5aba017434"
dependencies = [
"digest",
]
[[package]]
name = "polyval"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1"
dependencies = [
"cfg-if",
"cpufeatures",
"opaque-debug",
"universal-hash",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
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-gcm",
"anyhow",
"base64",
"cipher 0.4.3",
"clap",
"hkdf",
"log",
"rustls",
"scrypt",
"serde",
"serde_json",
"sha2",
]
[[package]]
name = "rustls"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84"
dependencies = [
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "ryu"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "salsa20"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686"
dependencies = [
"cipher 0.3.0",
]
[[package]]
name = "scrypt"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e73d6d7c6311ebdbd9184ad6c4447b2f36337e327bda107d3ba9e3c374f9d325"
dependencies = [
"hmac",
"password-hash",
"pbkdf2",
"salsa20",
"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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
dependencies = [
"cfg-if",
"cpufeatures",
"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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]]
name = "typenum"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "universal-hash"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
dependencies = [
"generic-array",
"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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

20
Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[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-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"

1
README.md Normal file
View File

@ -0,0 +1 @@
# RustCryptFS

28
src/args.rs Normal file
View File

@ -0,0 +1,28 @@
use clap::{Parser, Subcommand};
#[derive(Debug, Parser)]
#[clap(author, version, about, long_about = None)]
pub(crate) struct Args {
#[clap(subcommand)]
pub(crate) command: Commands,
}
#[derive(Debug, Subcommand)]
pub(crate) enum Commands {
/// Decrypt a file
Decrypt(DecryptCommand),
}
#[derive(Debug, Parser)]
pub(crate) struct DecryptCommand {
/// The file to decrypt
pub(crate) file_path : String,
/// Path to the gocryptfs.conf
#[clap(short('c'), long)]
pub(crate) gocryptfs_conf_path : Option<String>,
/// The password
#[clap(short, long)]
pub(crate) password : Option<String>
}

124
src/config.rs Normal file
View File

@ -0,0 +1,124 @@
use std::collections::HashSet;
use aes_gcm::{
aead::{generic_array::GenericArray, AeadInPlace},
aes::Aes256,
AesGcm, Key, NewAead,
};
use hkdf::Hkdf;
#[derive(serde::Deserialize, Debug, PartialEq, Eq, Hash)]
pub(crate) enum FeatureFlag {
/// FlagPlaintextNames indicates that filenames are unencrypted.
PlaintextNames,
/// FlagDirIV indicates that a per-directory IV file is used.
DirIV,
/// FlagEMENames indicates EME (ECB-Mix-ECB) filename encryption.
///
/// This flag is mandatory since gocryptfs v1.0.
EMENames,
/// FlagGCMIV128 indicates 128-bit GCM IVs.
///
/// This flag is mandatory since gocryptfs v1.0, except when XChaCha20Poly1305 is used.
GCMIV128,
/// FlagLongNames allows file names longer than 175 bytes.
LongNames,
/// FlagLongNameMax sets a custom name length limit, names longer than that will be hashed.
LongNameMax,
/// FlagAESSIV selects an AES-SIV based crypto backend.
AESSIV,
/// FlagRaw64 enables raw (unpadded) base64 encoding for file names.
Raw64,
/// FlagHKDF enables HKDF-derived keys for use with GCM, EME and SIV
/// instead of directly using the master key (GCM and EME) or the SHA-512
/// hashed master key (SIV).
///
/// Note that this flag does not change the password hashing algorithm
/// which always is scrypt.
HKDF,
/// FlagFIDO2 means that "-fido2" was used when creating the filesystem.
///
/// The masterkey is protected using a FIDO2 token instead of a password.
FIDO2,
/// FlagXChaCha20Poly1305 means we use XChaCha20-Poly1305 file content encryption
XChaCha20Poly1305,
}
#[derive(serde::Deserialize, Debug)]
pub(crate) struct CryptConf {
#[serde(rename = "Creator")]
creator: String,
#[serde(rename = "EncryptedKey")]
encrypted_key: String,
#[serde(rename = "ScryptObject")]
pub scrypt_object: ScryptObject,
#[serde(rename = "Version")]
version: u8,
#[serde(rename = "FeatureFlags")]
feature_flags: HashSet<FeatureFlag>,
}
impl CryptConf {
pub(crate) fn get_master_key(&self, password: &[u8]) -> anyhow::Result<Vec<u8>> {
let block = base64::decode(&self.encrypted_key)?;
let key = self.scrypt_object.get_hkdf_key(password)?;
let nonce = &block[..16];
let tag = &block[block.len() - 16..];
let ciphertext = &block[16..block.len() - 16];
let mut buf = Vec::from(ciphertext);
let aes = AesGcm::<Aes256, cipher::consts::U16>::new(Key::from_slice(&key));
aes.decrypt_in_place_detached(
GenericArray::from_slice(&nonce),
&[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 {
self.feature_flags.contains(flag)
}
}
#[derive(serde::Deserialize, Debug)]
pub(crate) struct ScryptObject {
#[serde(rename = "Salt")]
salt: String,
#[serde(rename = "N")]
n: u32,
#[serde(rename = "R")]
r: u32,
#[serde(rename = "P")]
p: u32,
#[serde(rename = "KeyLen")]
key_len: u32,
}
impl ScryptObject {
pub(crate) fn get_hkdf_key(&self, password: &[u8]) -> anyhow::Result<Vec<u8>> {
let mut key = [0u8; 32];
let params = scrypt::Params::new((self.n as f64).log2() as u8, self.r, self.p)?;
scrypt::scrypt(
password,
&base64::decode(&self.salt).unwrap(),
&params,
&mut key,
)?;
let hdkf = Hkdf::<sha2::Sha256>::new(None, &key);
hdkf.expand(b"AES-GCM file content encryption", &mut key)
.unwrap();
Ok(key.to_vec())
}
}

71
src/content_enc.rs Normal file
View File

@ -0,0 +1,71 @@
use aes_gcm::{
aead::generic_array::GenericArray, aes::Aes256, AeadInPlace, NewAead, AesGcm,
};
use cipher::consts::U32;
use hkdf::Hkdf;
pub struct ContentEnc {
key: GenericArray<u8, U32>,
iv_len: usize,
}
impl ContentEnc {
pub fn new(master_key: &[u8], iv_len: u8) -> Self {
let mut key = [0u8; 32];
let hdkf = Hkdf::<sha2::Sha256>::new(None, &master_key);
hdkf.expand(b"AES-GCM file content encryption", &mut key)
.unwrap();
Self {
key: GenericArray::from(key),
iv_len: iv_len as usize,
}
}
pub fn decrypt_block(
&self,
block: &[u8],
block_number: u64,
file_id: Option<&[u8]>,
) -> anyhow::Result<Vec<u8>> {
// TODO NOT BOX
if block.len() == 0 {
return Ok(block.into());
}
if block.iter().all(|f| *f == 0) {
todo!("black hole")
}
if block.len() < self.iv_len {
return Err(anyhow::Error::msg("Block is too short"));
}
let nonce = &block[..self.iv_len];
let tag = &block[block.len() - self.iv_len..];
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"));
}
let mut buf = Vec::from(ciphertext);
let mut aad = Vec::from(block_number.to_be_bytes());
if let Some(file_id) = file_id {
aad.extend(file_id);
}
let aes = AesGcm::<Aes256, cipher::consts::U16>::new(&self.key);
aes.decrypt_in_place_detached(
GenericArray::from_slice(nonce),
&aad,
&mut buf,
GenericArray::from_slice(tag),
)
.unwrap();
return Ok(buf);
}
}

69
src/main.rs Normal file
View File

@ -0,0 +1,69 @@
use std::{
fs::{self, File},
io::{BufWriter, Read, Write},
path::{Path, PathBuf},
};
use anyhow::Context;
use args::DecryptCommand;
use clap::Parser;
use crate::content_enc::ContentEnc;
mod args;
mod config;
mod content_enc;
fn main() -> anyhow::Result<()> {
let args = args::Args::parse();
log::debug!("{:?}", args);
match &args.command {
args::Commands::Decrypt(c) => decrypt_file(c),
}
}
fn decrypt_file(c: &DecryptCommand) -> anyhow::Result<()> {
let file_path = Path::new(&c.file_path);
let config_path = c
.gocryptfs_conf_path
.as_ref()
.map(|p| PathBuf::from(p))
.unwrap_or_else(|| file_path.parent().unwrap().join("gocryptfs.conf"));
let content = fs::read_to_string(config_path)?;
let conf: config::CryptConf =
serde_json::from_str(&content).context("Failed to decode configuration")?;
let mut file = File::open(file_path).unwrap();
let master_key = conf.get_master_key(c.password.as_ref().unwrap().as_bytes())?;
let enc = ContentEnc::new(&master_key, 16);
let mut buf = [0u8; 18];
let n = file.read(&mut buf)?;
let id = if n < 18 { None } else { Some(&buf[2..]) };
let mut buf = [0u8; 4096 + 32];
let stdout = std::io::stdout();
let mut stdout = BufWriter::new(stdout.lock());
let mut block_index = 0;
loop {
let n = file.read(&mut buf)?;
let res = enc.decrypt_block(&buf[..n], block_index, id)?;
stdout.write_all(&res)?;
if res.len() == 0 {
break;
}
block_index += 1;
}
stdout.flush()?;
Ok(())
}