diff --git a/Cargo.lock b/Cargo.lock index 2044b05..f156c9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -144,6 +144,30 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "async-compression" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-recursion" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c5ef0ede93efbf733c1a727f3b6b5a1060bbedd5600183e66f6e4be4af0ec5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -183,6 +207,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "autotools" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8da1805e028a172334c3b680f93e71126f2327622faef2ec3d893c0a4ad77" +dependencies = [ + "cc", +] + [[package]] name = "axum" version = "0.6.20" @@ -228,6 +261,20 @@ dependencies = [ "tower-service", ] +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "futures-core", + "getrandom", + "instant", + "pin-project-lite", + "rand", + "tokio", +] + [[package]] name = "backtrace" version = "0.3.69" @@ -261,6 +308,16 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +[[package]] +name = "base64-serde" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba368df5de76a5bea49aaf0cf1b39ccfbbef176924d1ba5db3e4135216cbe3c7" +dependencies = [ + "base64 0.21.7", + "serde", +] + [[package]] name = "base64ct" version = "1.6.0" @@ -404,6 +461,17 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + [[package]] name = "bucket-common-types" version = "0.1.0" @@ -443,8 +511,9 @@ dependencies = [ "bucket-common-types", "byte-unit", "bytemuck", - "cookie", + "cookie 0.18.0", "criterion", + "dash-mpd", "ed25519-compact", "email_address", "fuser", @@ -457,6 +526,7 @@ dependencies = [ "log", "lunchbox", "mime", + "mnemonic", "once_cell", "opaque-ke", "passkey", @@ -681,6 +751,16 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -706,6 +786,17 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "cookie" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + [[package]] name = "cookie" version = "0.18.0" @@ -720,6 +811,33 @@ dependencies = [ "version_check", ] +[[package]] +name = "cookie_store" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" +dependencies = [ + "cookie 0.17.0", + "idna 0.3.0", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -745,6 +863,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + [[package]] name = "criterion" version = "0.5.1" @@ -948,6 +1075,45 @@ dependencies = [ "syn 2.0.53", ] +[[package]] +name = "dash-mpd" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18c18f28b58beade78e0f61a846a63a122cb92c5f5ed6bad29d7ad13287c7526" +dependencies = [ + "async-recursion", + "backoff", + "base64 0.21.7", + "base64-serde", + "bstr", + "chrono", + "colored", + "data-url", + "ffprobe", + "file-format", + "fs-err", + "governor", + "hex-literal", + "iso8601", + "lazy_static", + "num-traits", + "pssh-box", + "quick-xml", + "regex", + "reqwest", + "sanitise-file-name", + "serde", + "serde_path_to_error", + "serde_with", + "tempfile", + "thiserror", + "tokio", + "tracing", + "url", + "xattr", + "xmltree", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -967,6 +1133,12 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +[[package]] +name = "data-url" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" + [[package]] name = "der" version = "0.7.8" @@ -1121,6 +1293,15 @@ dependencies = [ "serde", ] +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1163,24 +1344,65 @@ dependencies = [ "subtle", ] +[[package]] +name = "ffprobe" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5d603974ab029fc75cebf00bfa06c9c6f49a6fb657f4f5f6a9fd6cbd76910a4" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "fiat-crypto" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" +[[package]] +name = "file-format" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ba1b81b3c213cf1c071f8bf3b83531f310df99642e58c48247272eef006cae5" + [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1190,6 +1412,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + [[package]] name = "funty" version = "2.0.0" @@ -1282,6 +1513,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.30" @@ -1697,6 +1934,26 @@ dependencies = [ "syn 2.0.53", ] +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand", + "smallvec", + "spinning_top", +] + [[package]] name = "group" version = "0.13.0" @@ -1843,6 +2100,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hxdmp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b27f28a7466846baca75f0a5244e546e44178eb7f1c07a3820f413e91c6b0" + [[package]] name = "hyper" version = "0.14.28" @@ -1879,6 +2142,19 @@ dependencies = [ "tokio-io-timeout", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -1908,6 +2184,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "0.5.0" @@ -1958,6 +2244,21 @@ dependencies = [ "generic-array", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is-terminal" version = "0.4.12" @@ -1969,6 +2270,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "iso8601" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153" +dependencies = [ + "nom", +] + [[package]] name = "itertools" version = "0.10.5" @@ -2134,12 +2444,42 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mnemonic" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b8f3a258db515d5e91a904ce4ae3f73e091149b90cadbdb93d210bee07f63b" + [[package]] name = "multimap" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "nom" version = "7.1.3" @@ -2150,6 +2490,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "num-bigint" version = "0.4.4" @@ -2195,6 +2541,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.53", +] + [[package]] name = "object" version = "0.32.2" @@ -2244,6 +2611,50 @@ dependencies = [ "zeroize", ] +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "p256" version = "0.13.2" @@ -2323,7 +2734,7 @@ checksum = "f14d42b14749cc7927add34a9932b3b3cc5349a633384850baa67183061439dd" dependencies = [ "ciborium", "coset", - "idna", + "idna 0.5.0", "passkey-authenticator", "passkey-types", "public-suffix", @@ -2556,6 +2967,12 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2725,6 +3142,50 @@ dependencies = [ "prost", ] +[[package]] +name = "protobuf-src" +version = "1.1.0+21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ac8852baeb3cc6fb83b93646fb93c0ffe5d14bf138c945ceb4b9948ee0e3c1" +dependencies = [ + "autotools", +] + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "pssh-box" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d0f24d6df7a94002c1a3d365d606e2fda2f81d0b569cce73b5cdb2b32457989" +dependencies = [ + "anyhow", + "base64 0.21.7", + "bstr", + "byteorder", + "bytes", + "hex", + "hex-literal", + "hxdmp", + "num_enum", + "prost", + "prost-build", + "prost-types", + "protobuf-src", + "quick-xml", + "serde", + "serde-xml-rs", + "serde_json", + "serde_path_to_error", + "serde_with", + "tracing", + "zerocopy", +] + [[package]] name = "ptr_meta" version = "0.1.4" @@ -2751,12 +3212,47 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca346b8ff0739660876c8d96a6f9de5cd9b4cd87500bb0ce92485318c674afe" +[[package]] +name = "publicsuffix" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +dependencies = [ + "idna 0.3.0", + "psl-types", +] + +[[package]] +name = "quanta" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca0b7bac0b97248c40bb77288fc52029cf1459c0461ea1b05ee32ccf011de2c" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + [[package]] name = "quick-error" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quote" version = "1.0.35" @@ -2802,6 +3298,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "raw-cpuid" +version = "11.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" +dependencies = [ + "bitflags 2.4.2", +] + [[package]] name = "rayon" version = "1.9.0" @@ -2875,6 +3380,51 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "async-compression", + "base64 0.21.7", + "bytes", + "cookie 0.17.0", + "cookie_store", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-socks", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -2979,6 +3529,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -3000,6 +3559,21 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "sanitise-file-name" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d36299972b96b8ae7e8f04ecbf75fb41a27bf3781af00abcf57609774cb911" + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -3033,6 +3607,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.22" @@ -3070,6 +3667,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde-xml-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" +dependencies = [ + "log", + "serde", + "thiserror", + "xml-rs", +] + [[package]] name = "serde_derive" version = "1.0.197" @@ -3093,6 +3702,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.5" @@ -3274,6 +3893,15 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" @@ -3386,6 +4014,27 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -3530,6 +4179,28 @@ dependencies = [ "syn 2.0.53", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.15" @@ -3837,7 +4508,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna", + "idna 0.5.0", "percent-encoding", ] @@ -3858,6 +4529,12 @@ dependencies = [ "serde", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -4264,6 +4941,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "wyz" version = "0.5.1" @@ -4285,6 +4972,32 @@ dependencies = [ "zeroize", ] +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + +[[package]] +name = "xml-rs" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + [[package]] name = "yansi" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index d934289..91bddd9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,12 +5,22 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] +default = ["web"] s3 = [] proto = [] wasm = [] +# Stream API compatibility, mpeg-dash video stream support +stream = [] +# Listen changes in the Storage, synchronization API support. for listening and parsing webhook events. +sync = [] +# Compress files before transit. +compression = [] +# + web = ["wasm", "proto"] cli = ["proto", "s3", "native"] native = [] #"dep:tokio", "dep:tokio-stream" + [dependencies] bucket-common-types = { git = "https://github.com/Tim-Leon/bucket-common-types.git", features = [ "secret_share_link", @@ -60,6 +70,8 @@ pkg-version = "1.0.0" log = "0.4.20" prokio = "0.1.0" email_address = "0.2.4" +mnemonic = "1.1.1" +dash-mpd = {version = "0.15.0", features = ["tokio"],optional = true} [target.'cfg(unix)'.dependencies] fuser = "0.14.0" # https://crates.io/crates/fuser diff --git a/src/controller/account/authentication.rs b/src/controller/account/authentication.rs index 9922ef0..ecf5b71 100644 --- a/src/controller/account/authentication.rs +++ b/src/controller/account/authentication.rs @@ -2,6 +2,7 @@ use crate::client::query_client::backend_api::{AccountLoginFinishRequest, Accoun use crate::client::query_client::QueryClient; use crate::controller::account::errors::{LoginError, RegisterError}; +use crate::encryption_v1::encryption::create_ed25519_signing_keys; use crate::encryption_v1::hash::password_strength; use crate::{ constants::PASSWORD_STRENGTH_SCORE, @@ -86,7 +87,7 @@ pub async fn register( if password_strength(&email, &password, None)? < PASSWORD_STRENGTH_SCORE { return Err(RegisterError::PasswordTooWeak); } - let secrets = encryption_v1::encryption::setup(password, email)?; + let master_key = encryption_v1::encryption::setup(password, email)?; let mut rng = rand::thread_rng(); let oprf_start = opaque_ke::ClientRegistration::<DefaultCipherSuite>::start(&mut rng, password.as_bytes()) @@ -109,11 +110,13 @@ pub async fn register( ClientRegistrationFinishParameters::default(), )?; + let signing_key = create_ed25519_signing_keys(&master_key).unwrap(); + let finish_req = CreateAccountFinishRequest { oprf: oprf_finish.message.serialize().to_vec(), username: username.to_string(), session_id: start_resp.session_id, - public_signing_key: secrets.get_ed25519_public_signing_key().as_slice().to_vec(), + public_signing_key: signing_key.pk.to_vec(), }; let finish_resp = query_client .create_account_finish(finish_req) diff --git a/src/controller/bucket/download_handler.rs b/src/controller/bucket/download_handler.rs index 272acb8..e739ecc 100644 --- a/src/controller/bucket/download_handler.rs +++ b/src/controller/bucket/download_handler.rs @@ -88,12 +88,12 @@ impl BucketFileDownloadHandler for WebBucketFileWriter { match decrypted_buffer { Either::Left(decrypted_buffer) => { self.write_target_file - .write_chunk(&decrypted_buffer, self.offset); + .write_chunk(&decrypted_buffer, self.offset).unwrap(); self.offset += decrypted_buffer.len() as u64; } Either::Right(decrypted_buffer) => { self.write_target_file - .write_chunk(&decrypted_buffer, self.offset); + .write_chunk(&decrypted_buffer, self.offset).unwrap(); self.offset += decrypted_buffer.len() as u64; } } @@ -120,7 +120,7 @@ impl BucketFileDownloadHandler for WebBucketFileWriter { match self.decryption_module { None => {} Some(module) => { - module.finalize()?; //TODO: Invalid Signature + module.finalize(); //TODO: Invalid Signature } } diff --git a/src/controller/bucket/upload_handler.rs b/src/controller/bucket/upload_handler.rs index f712a0a..3033f95 100644 --- a/src/controller/bucket/upload_handler.rs +++ b/src/controller/bucket/upload_handler.rs @@ -38,7 +38,7 @@ pub trait BucketFileUploadHandler { // Called when a chunk is uploaded. returns the chunk to be uploaded. It's up to the implementation to encrypt the chunk if the bucket is encrypted. async fn on_upload_chunk(&mut self, chunk_size: u64) -> Result<Vec<u8>, Self::Error>; // Called when the last chunk has been uploaded. In this method the user is still able to upload data, if so it will return a Vec. - fn on_upload_finish(self) -> Result<Option<Vec<u8>>, Self::Error>; + fn on_upload_finish(self) -> Result<(), Self::Error>; } #[async_trait(?Send)] @@ -56,7 +56,8 @@ impl BucketFileUploadHandler for BucketFileReader { ) -> Result<u64, Self::Error> { match bucket_encryption { Some(_bucket_encryption) => match &self.encryption_module { - Some(_encryption_module) => {} + Some(_encryption_module) => { + } None => { return Err(BucketDownloadHandlerFileErrors::EncryptionModuleNotInitialized); } @@ -76,18 +77,18 @@ impl BucketFileUploadHandler for BucketFileReader { match &mut self.encryption_module { Some(x) => { - let decrypted_bytes = x.update(bytes)?; - Ok(decrypted_bytes) + let encrypted_bytes = x.update(bytes)?; + Ok(encrypted_bytes) } None => Ok(bytes), } } - fn on_upload_finish(self) -> Result<Option<Vec<u8>>, Self::Error> { - let signed_hash: Option<Vec<u8>> = match self.encryption_module { - Some(x) => Some(x.finalize()?), + fn on_upload_finish(self) -> Result<(), Self::Error> { + let signed_hash = match self.encryption_module { + Some(x) => Some(x.finalize()), None => return Err(Self::Error::EncryptionModuleNotInitialized), }; - Ok(signed_hash) + Ok(()) } } diff --git a/src/encryption_v1/constants.rs b/src/encryption_v1/constants.rs index 2d4a9c3..f6e22c5 100644 --- a/src/encryption_v1/constants.rs +++ b/src/encryption_v1/constants.rs @@ -21,3 +21,5 @@ pub const HIGHWAY_HASH_KEY: [u64; 4] = [ ]; pub const V1_ENCRYPTION_PASSWORD_SALT: &str = ""; + +pub const V1_X25519_SIGNATURE_HASH_SALT:&str = ""; \ No newline at end of file diff --git a/src/encryption_v1/decryption_module.rs b/src/encryption_v1/decryption_module.rs index cff13de..23cff56 100644 --- a/src/encryption_v1/decryption_module.rs +++ b/src/encryption_v1/decryption_module.rs @@ -9,30 +9,28 @@ use highway::HighwayHash; use crate::encryption_v1::constants::{ AES_GCM_NONCE, HIGHWAY_HASH_KEY, SHARE_LINK_SIGNATURE_NOISE, }; -use crate::encryption_v1::encryption::{generate_bucket_encryption_key, ClientSecrets}; +use crate::encryption_v1::encryption::{generate_bucket_encryption_key, MasterKey}; + +use super::hash_based_signature::Ed25519HighwayHashBasedSignature; pub trait DecryptionModule { type Error; /// Returns vector of decrypted data fn update(&mut self, ciphertext: impl AsRef<[u8]>) -> Result<Vec<u8>, Self::Error>; - /// Finalize decryption by returning Vector which could contain hash/signature, get creative. - fn finalize(self) -> Result<(), Self::Error>; + fn finalize(self); } #[derive(Clone)] pub struct ZeroKnowledgeDecryptionModuleV1 { - secrets: Arc<ClientSecrets>, + secrets: Arc<MasterKey>, bucket_symmetric_encryption_key: aes_gcm::Aes256Gcm, - hasher: highway::HighwayHasher, nonce: Nonce<typenum::U12>, - ed25519_noise: Noise, - signature: Option<Signature>, + hash_based_signature: Option<Ed25519HighwayHashBasedSignature>, } impl ZeroKnowledgeDecryptionModuleV1 { pub fn new( - secrets: Arc<ClientSecrets>, + secrets: Arc<MasterKey>, bucket_id: &uuid::Uuid, - signature: Option<Signature>, ) -> Self { Self { secrets: secrets.clone(), @@ -41,10 +39,8 @@ impl ZeroKnowledgeDecryptionModuleV1 { bucket_id, ) .unwrap(), - hasher: highway::HighwayHasher::new(highway::Key(HIGHWAY_HASH_KEY)), nonce: *Nonce::from_slice(&AES_GCM_NONCE), //TODO: NONCE should come from the bucket name? - ed25519_noise: Noise::from_slice(&SHARE_LINK_SIGNATURE_NOISE).unwrap(), - signature, + hash_based_signature: None } } } @@ -60,26 +56,15 @@ pub enum DecryptionError { impl DecryptionModule for ZeroKnowledgeDecryptionModuleV1 { type Error = DecryptionError; fn update(&mut self, ciphertext: impl AsRef<[u8]>) -> Result<Vec<u8>, Self::Error> { - self.hasher.append(ciphertext.as_ref()); let plaintext = self .bucket_symmetric_encryption_key .decrypt(&self.nonce, ciphertext.as_ref()) .map_err(DecryptionError::FailedToDecryptChunk)?; Ok(plaintext) } - - fn finalize(self) -> Result<(), Self::Error> { - let hash_result = self.hasher.finalize256(); - match self.signature { - None => {} - Some(signature) => { - self.secrets - .ed25519_keypair - .pk - .verify(bytemuck::bytes_of(&hash_result), &signature) - .map_err(DecryptionError::InvalidSignature)?; - } - } - Ok(()) + + fn finalize(self) { + } + } diff --git a/src/encryption_v1/encryption.rs b/src/encryption_v1/encryption.rs index a450af2..a6847c4 100644 --- a/src/encryption_v1/encryption.rs +++ b/src/encryption_v1/encryption.rs @@ -3,6 +3,7 @@ use aes_gcm::{ aead::{generic_array::typenum, Aead}, KeyInit, Nonce, }; +use argon2::password_hash::SaltString; use std::sync::Arc; //use sha2::Sha512; @@ -13,8 +14,10 @@ use crate::encryption_v1::hash::{ use highway::HighwayHash; -use sha3::{digest::InvalidLength, Digest}; +use sha3::{digest::InvalidLength, Digest, Sha3_256}; use std::str; + +use super::constants::V1_X25519_SIGNATURE_HASH_SALT; // struct DefaultCipherSuite; // impl CipherSuite for DefaultCipherSuite { // type OprfCs = opaque_ke::Ristretto255; @@ -76,104 +79,46 @@ pub enum EncryptionSetupError { * TODO: Fuzz input * MUST BE DETERMINISTIC */ -pub fn setup(password: &str, email: &str) -> Result<ClientSecrets, EncryptionSetupError> { - let master_key = argon2id_hash_password(password, email, V1_ENCRYPTION_PASSWORD_SALT)?; - let seed = ed25519_compact::Seed::from_slice(master_key[0..32].as_bytes()).unwrap(); - let ed25519_keypair = ed25519_compact::KeyPair::from_seed(seed); //from_slice(master_key.as_bytes().take).unwrap(); - Ok(ClientSecrets { - master_key, - ed25519_keypair, +pub fn setup(password: &str, email: &str) -> Result<MasterKey, EncryptionSetupError> { + let salt = SaltString::from_b64(&V1_ENCRYPTION_PASSWORD_SALT).map_err(PasswordHashErrors::PasswordHashError)?; + let master_key = argon2id_hash_password(password, email, salt.as_salt())? + .hash + .unwrap(); + Ok(MasterKey { + 0: master_key.to_string(), }) } + + +pub fn create_ed25519_signing_keys(master_key: &MasterKey) -> Result<ed25519_compact::KeyPair, ed25519_compact::Error>{ + let mut hasher = Sha3_256::new(); + hasher.update(master_key.0.as_bytes()); + hasher.update(V1_X25519_SIGNATURE_HASH_SALT); + let slice = hasher.finalize(); + let seed = ed25519_compact::Seed::from_slice(&slice).unwrap(); //[0..32] + let ed25519_key_pair = ed25519_compact::KeyPair::from_seed(seed); + Ok(ed25519_key_pair) +} + pub fn generate_bucket_encryption_key( - secrets: Arc<ClientSecrets>, + master_key: Arc<MasterKey>, bucket_id: &uuid::Uuid, ) -> Result<aes_gcm::Aes256Gcm, InvalidLength> { - let bucket_key = bucket_key_hash_sha256(secrets.master_key.clone(), bucket_id); + let bucket_key = bucket_key_hash_sha256(&master_key, bucket_id); //let aes_gcm_key = aes_gcm::Key::<aes_gcm::Aes256Gcm>::from_slice(bucket_key.as_slice()); let aes_gcm_key = aes_gcm::Aes256Gcm::new_from_slice(bucket_key.as_slice()); aes_gcm_key } - -#[derive(zeroize::Zeroize, Clone)] -pub struct ClientSecrets { - master_key: String, - pub ed25519_keypair: ed25519_compact::KeyPair, -} - -impl ClientSecrets { - pub fn get_ed25519_public_signing_key(&self) -> ed25519_compact::PublicKey { - self.ed25519_keypair.pk - } +#[derive(zeroize::Zeroize)] +pub struct Secrets { + pub master_key: MasterKey, + pub signing_key: ed25519_compact::KeyPair, } -/* -Use the aes_gcm symetric key to encrypt the file content. -Use HighwayHash to hash the encrypted file content. -Use the ed25519 keypair to sign the hash. -*/ -pub async fn encrypted_upload_files( - aes_gcm_symmetric_key: &aes_gcm::Key<aes_gcm::Aes256Gcm>, - ed25519_signing_key: &ed25519_compact::KeyPair, - file: gloo::file::File, - upload_fn: fn(&[u8]), - upload_finish: fn(&[u8]), -) { - let key = highway::Key([1, 2, 3, 4]); - let mut highway_hash = highway::HighwayHasher::new(key); - let filename = file.name(); - let aes_gcm_cipher = aes_gcm::Aes256Gcm::new_from_slice(aes_gcm_symmetric_key).unwrap(); - let nonce = aes_gcm::Nonce::from_slice(filename.as_bytes()); //TODO: Fix - //let mut file_bytes = file.bytes(); - //file.read_to_end(&mut file_bytes); - //TODO: Chunk it. Read 1MB at a time. - //let file_reader = gloo::file::futures::read_as_array_bytes(&file, read_fn); - let file_size = file.size(); - // Iterate over the file in 1MB chunks, - // encrypt each chunk while also hashing it. - // Then upload the encrypted chunk. - // After the file is uploaded, sign the hash, upload the hash signature. - // Done! - for _it in 0..&file_size / 1024 { - let chunk_data = gloo::file::futures::read_as_bytes(&file).await.unwrap(); //TODO: What if file is too big for memory? - let ciphertext = aes_gcm_cipher - .encrypt(nonce, chunk_data.as_slice()) - .unwrap(); - highway_hash.append(&ciphertext); - upload_fn(&ciphertext); - } - let hash = highway_hash.finalize256(); - let signature = ed25519_signing_key.sk.sign(bytemuck::bytes_of(&hash), None); - // Upload - upload_finish(signature.as_slice()); -} - -pub async fn encrypt_chunk( - aes_gcm_symmetric_key: &aes_gcm::Key<aes_gcm::Aes256Gcm>, - nonce: &Nonce<typenum::U12>, - _ed25519_signing_key: &ed25519_compact::KeyPair, - highway_hash: &mut highway::HighwayHasher, - chunk_data: Vec<u8>, -) -> Vec<u8> { - let aes_gcm_cipher = aes_gcm::Aes256Gcm::new(aes_gcm_symmetric_key); - let ciphertext = aes_gcm_cipher - .encrypt(nonce, chunk_data.as_slice()) - .unwrap(); - highway_hash.append(&ciphertext); - ciphertext -} - -// pub async fn encrypt_finalize( -// ed25519_signing_key: &ed25519_compact::KeyPair, -// highway_hash: &mut highway::HighwayHasher, -// ) -> Signature { -// let hash = highway_hash.finalize256(); -// let signature = ed25519_signing_key.sk.sign(&bytemuck::bytes_of(&hash), None); -// signature -// } +#[derive(zeroize::Zeroize, Clone)] +pub struct MasterKey (pub String); -//pub fn generate_rsa_keypair() #[cfg(test)] mod tests { diff --git a/src/encryption_v1/encryption_module.rs b/src/encryption_v1/encryption_module.rs index 940143c..60c0ea9 100644 --- a/src/encryption_v1/encryption_module.rs +++ b/src/encryption_v1/encryption_module.rs @@ -3,29 +3,29 @@ use std::sync::Arc; use aes_gcm::aead::generic_array::typenum; use aes_gcm::aead::Aead; use aes_gcm::Nonce; -use ed25519_compact::Noise; use highway::HighwayHash; use crate::encryption_v1::constants::{ AES_GCM_NONCE, HIGHWAY_HASH_KEY, SHARE_LINK_SIGNATURE_NOISE, }; -use crate::encryption_v1::encryption::{generate_bucket_encryption_key, ClientSecrets}; +use crate::encryption_v1::encryption::{generate_bucket_encryption_key, MasterKey}; + +use super::hash_based_signature::{Ed25519HighwayHashBasedSignature, HashBasedSignature}; pub trait EncryptionModule: Clone + Sized{ type Error; /// Returns vector of encrypted data fn update(&mut self, plaintext: impl AsRef<[u8]>) -> Result<Vec<u8>, Self::Error>; /// Finalize encryption by returning Vector which could contain hash/signature, get creative. - fn finalize(self) -> Result<Vec<u8>, Self::Error>; + fn finalize(self); } #[derive(Clone)] pub struct ZeroKnowledgeEncryptionModuleV1 { - secrets: Arc<ClientSecrets>, + secrets: Arc<MasterKey>, bucket_symmetric_encryption_key: aes_gcm::Aes256Gcm, - hasher: highway::HighwayHasher, nonce: Nonce<typenum::U12>, - ed25519_noise: Noise, + hash_based_signature: Option<Ed25519HighwayHashBasedSignature>, } #[derive(Debug, thiserror::Error)] @@ -35,7 +35,7 @@ pub enum EncryptionError { } impl ZeroKnowledgeEncryptionModuleV1 { - pub fn new(secrets: Arc<ClientSecrets>, bucket_id: &uuid::Uuid) -> Self { + pub fn new(secrets: Arc<MasterKey>, bucket_id: &uuid::Uuid) -> Self { Self { secrets: secrets.clone(), bucket_symmetric_encryption_key: generate_bucket_encryption_key( @@ -43,9 +43,8 @@ impl ZeroKnowledgeEncryptionModuleV1 { bucket_id, ) .unwrap(), - hasher: highway::HighwayHasher::new(highway::Key(HIGHWAY_HASH_KEY)), - nonce: *Nonce::from_slice(&AES_GCM_NONCE), //TODO: NONCE should come from the bucket name? - ed25519_noise: Noise::from_slice(&SHARE_LINK_SIGNATURE_NOISE).unwrap(), + nonce: *Nonce::from_slice(&AES_GCM_NONCE), + hash_based_signature: None, } } } @@ -57,17 +56,11 @@ impl EncryptionModule for ZeroKnowledgeEncryptionModuleV1 { .bucket_symmetric_encryption_key .encrypt(&self.nonce, plaintext.as_ref()) .map_err(EncryptionError::FailedToEncryptChunk)?; - self.hasher.append(&ciphertext); Ok(ciphertext) } - fn finalize(self) -> Result<Vec<u8>, Self::Error> { - let hash_result = self.hasher.finalize256(); - let signature = self - .secrets - .ed25519_keypair - .sk - .sign(bytemuck::bytes_of(&hash_result), Some(self.ed25519_noise)); - Ok(signature.to_vec()) + fn finalize(self) { + } + } diff --git a/src/encryption_v1/hash.rs b/src/encryption_v1/hash.rs index bc6622b..b354611 100644 --- a/src/encryption_v1/hash.rs +++ b/src/encryption_v1/hash.rs @@ -1,10 +1,12 @@ use crate::constants::PASSWORD_STRENGTH_SCORE; use aes_gcm::aead::generic_array::{typenum, GenericArray}; -use argon2::password_hash::SaltString; -use argon2::{Argon2, PasswordHasher}; +use argon2::password_hash::{Salt, SaltString}; +use argon2::{Argon2, PasswordHash, PasswordHasher}; use base64::engine::Engine; use sha3::{Digest, Sha3_256}; +use super::encryption::MasterKey; + #[derive(Debug, thiserror::Error)] pub enum PasswordHashErrors { //#[error("Email with too long username")] @@ -21,14 +23,17 @@ pub enum PasswordHashErrors { * Will be user to create the master key. This key is used to derive encryption keys and signing key for the user. * It is essential that the password is kept secret or all the encrypted data can be lost. */ -pub fn argon2id_hash_password( - password: &str, - email: &str, - salt_addon: &str, -) -> Result<String, PasswordHashErrors> { +pub fn argon2id_hash_password<'a, 'b>( + password: &'a str, + email: &'a str, + salt_addon: Salt<'a>, +) -> Result<PasswordHash<'b>, PasswordHashErrors> +// Specifically the salt must outlive the password hash. +where 'a:'b +{ // Hash the email with sha512 to get a 64 bytes hash. Which is the max size for argon2id salt. Perfect. let mut sha256_hasher = Sha3_256::new(); //Sha3_512::new(); - sha256_hasher.update(salt_addon.as_bytes()); // This is just additional entropy to make the email more unique. Might be useful? + sha256_hasher.update(salt_addon.as_str().as_bytes()); // This is just additional entropy to make the email more unique. Might be useful? sha256_hasher.update(email.as_bytes()); let email_hash: GenericArray<_, _> = sha256_hasher.finalize(); let _password_strength = password_strength(email, password, None)?; @@ -38,12 +43,13 @@ pub fn argon2id_hash_password( // Base64 expand size by 1/3 let encoded = base64::engine::general_purpose::STANDARD_NO_PAD.encode(email_hash.as_slice()); - let salt = SaltString::from_b64(&encoded).map_err(PasswordHashErrors::PasswordHashError)?; + //let salt = SaltString::from_b64(&encoded).map_err(PasswordHashErrors::PasswordHashError)?; .as_salt() let argon2id = Argon2::default(); let password_hash = argon2id - .hash_password(password.as_bytes(), salt.as_salt()) + .hash_password(password.as_bytes(), salt_addon) .map_err(PasswordHashErrors::PasswordHashError)?; - Ok(password_hash.to_string()) + + Ok(password_hash) } #[derive(Debug, thiserror::Error)] @@ -84,12 +90,12 @@ pub fn password_strength( } pub fn bucket_key_hash_sha256( - password_hash: String, + password_hash: &MasterKey, bucket_id: &uuid::Uuid, ) -> GenericArray<u8, typenum::U32> { let mut hasher = Sha3_256::new(); //Sha3_512::new(); hasher.update(bucket_id.as_bytes()); - hasher.update(password_hash.to_string().as_bytes()); + hasher.update(password_hash.0.as_bytes()); hasher.finalize() } diff --git a/src/encryption_v1/hash_based_signature.rs b/src/encryption_v1/hash_based_signature.rs new file mode 100644 index 0000000..5b2d25a --- /dev/null +++ b/src/encryption_v1/hash_based_signature.rs @@ -0,0 +1,70 @@ +use ed25519_compact::{Noise, Signature, VerifyingState}; +use highway::{HighwayHash, HighwayHasher, Key}; + +use super::{ + constants::{HIGHWAY_HASH_KEY, SHARE_LINK_SIGNATURE_NOISE}, + encryption::MasterKey, +}; +// Used for creating signatures +pub trait HashBasedSignature: Clone + Sized { + type Error; + + fn update(&mut self, ciphertext: impl AsRef<[u8]>); + // Creates a signature. + fn finalize(self) -> Result<Signature, Self::Error>; +} + +#[derive(Clone)] +pub struct Ed25519HighwayHashBasedSignature { + highway_hash: highway::HighwayHasher, + secret_key: ed25519_compact::SecretKey, + ed25519_noise: Noise, + //signature: Option<Signature>, +} +#[derive(thiserror::Error, Debug)] +pub enum Ed25519HighwayHashBasedSignatureError { + #[error(transparent)] + Ed25519Error(#[from] ed25519_compact::Error), +} + +impl Ed25519HighwayHashBasedSignature { + // Either we are creating a signature or we provide a signature to verify. + fn new( + //master_key: &MasterKey, + secret_key: ed25519_compact::SecretKey, + //signature: Option<Signature>, + ) -> Result<Self, Ed25519HighwayHashBasedSignatureError> { + //let seed = ed25519_compact::Seed::from_slice(master_key.0.as_bytes()).unwrap(); //[0..32] + //let ed25519_signing_key_pair = ed25519_compact::KeyPair::from_seed(seed); //from_slice(master_key.as_bytes().take).unwrap(); + let key = highway::Key(HIGHWAY_HASH_KEY); + let highway_hash = highway::HighwayHasher::new(key); + let ed25519_noise = + ed25519_compact::Noise::from_slice(&SHARE_LINK_SIGNATURE_NOISE).unwrap(); + + Ok(Ed25519HighwayHashBasedSignature { + highway_hash, + secret_key: secret_key, + ed25519_noise, + //signature, + }) + } +} + +impl HashBasedSignature for Ed25519HighwayHashBasedSignature { + type Error = Ed25519HighwayHashBasedSignatureError; + + fn update(&mut self, ciphertext: impl AsRef<[u8]>) { + self.highway_hash.append(ciphertext.as_ref()) + } + + fn finalize(self) -> Result<Signature, Self::Error> { + let hash_result = self.highway_hash.finalize256(); + let signature = self + .secret_key + .sign(bytemuck::bytes_of(&hash_result), Some(self.ed25519_noise)); + + Ok(signature) + } +} + + diff --git a/src/encryption_v1/hash_based_signature_verifier.rs b/src/encryption_v1/hash_based_signature_verifier.rs new file mode 100644 index 0000000..f7bc26c --- /dev/null +++ b/src/encryption_v1/hash_based_signature_verifier.rs @@ -0,0 +1,38 @@ +use ed25519_compact::Signature; + + +pub trait HashBasedSignatureVerifier: Clone + Sized { + type Error; + + fn verify_hash(self, hash: impl AsRef<[u8]>) -> Result<(),Self::Error>; +} +#[derive(thiserror::Error, Debug)] +pub enum Ed25519HighwayHashBasedSignatureVerifierError { + +} + +#[derive(Clone)] +pub struct Ed25519HighwayHashBasedSignatureVerifier { + pub signature: Signature, + pub public_key: ed25519_compact::PublicKey, +} + +impl HashBasedSignatureVerifier for Ed25519HighwayHashBasedSignatureVerifier { + type Error = Ed25519HighwayHashBasedSignatureVerifier; + + fn verify_hash(self, hash: impl AsRef<[u8]>) -> Result<(),Self::Error> { + self.public_key.verify(hash, &self.signature)? + } +} + +impl Ed25519HighwayHashBasedSignatureVerifier { + fn new( + signature: Signature, + pk: ed25519_compact::PublicKey, + ) -> Result<Self, Ed25519HighwayHashBasedSignatureVerifierError>{ + Ok(Self { + signature, + public_key: pk, + }) + } +} diff --git a/src/encryption_v1/mod.rs b/src/encryption_v1/mod.rs index cd24b98..8f064b9 100644 --- a/src/encryption_v1/mod.rs +++ b/src/encryption_v1/mod.rs @@ -3,6 +3,8 @@ pub mod decryption_module; pub mod encryption; pub mod encryption_module; pub mod hash; +pub mod hash_based_signature; +mod hash_based_signature_verifier; #[cfg(test)] mod tests { diff --git a/src/lib.rs b/src/lib.rs index 52df742..bd5714a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,9 @@ pub mod constants; pub mod controller; pub mod dto; pub mod encryption_v1; -mod event; mod util; pub mod platform; -pub mod client; \ No newline at end of file +pub mod client; + +pub mod sync; +pub mod stream; diff --git a/src/stream/mod.rs b/src/stream/mod.rs new file mode 100644 index 0000000..bd458e6 --- /dev/null +++ b/src/stream/mod.rs @@ -0,0 +1 @@ +mod mpeg_dash; \ No newline at end of file diff --git a/src/stream/mpeg_dash.rs b/src/stream/mpeg_dash.rs new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/src/stream/mpeg_dash.rs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/event/event.rs b/src/sync/event.rs similarity index 99% rename from src/event/event.rs rename to src/sync/event.rs index 3c547dd..6eee661 100644 --- a/src/event/event.rs +++ b/src/sync/event.rs @@ -11,4 +11,7 @@ pub enum BucketEvent { BucketUpdated(String), } + + + //pub fn parse_bucket_event() diff --git a/src/event/mod.rs b/src/sync/mod.rs similarity index 100% rename from src/event/mod.rs rename to src/sync/mod.rs