From 035dabf8690d045d30989e0db7ce23e476f6ef12 Mon Sep 17 00:00:00 2001 From: Avril Date: Fri, 24 Sep 2021 14:39:05 +0100 Subject: [PATCH] Initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for transfer's current commit: Future small blessing − 末小吉 --- .gitignore | 2 + Cargo.lock | 1012 +++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 20 + src/args.rs | 60 +++ src/cha.rs | 40 ++ src/config.rs | 61 +++ src/ext.rs | 124 +++++ src/key.rs | 289 ++++++++++++ src/main.rs | 41 ++ src/send/handshake.rs | 20 + src/send/mod.rs | 5 + 11 files changed, 1674 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/args.rs create mode 100644 src/cha.rs create mode 100644 src/config.rs create mode 100644 src/ext.rs create mode 100644 src/key.rs create mode 100644 src/main.rs create mode 100644 src/send/handshake.rs create mode 100644 src/send/mod.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e2a3069 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +*~ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..734d2a8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1012 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ef4730490ad1c4eae5c4325b2a95f521d023e5c885853ff7aca0a6a1631db3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "async-compression" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443ccbb270374a2b1055fc72da40e1f237809cd6bb0e97e66d264cd138473a6" +dependencies = [ + "brotli", + "futures-core", + "memchr", + "pin-project-lite 0.2.7", + "tokio 1.12.0", +] + +[[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.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[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.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71cb90ade945043d3d53597b2fc359bb063db8ade2bcffe7997351d0756e9d50" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "build_const" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7" + +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cc" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color-eyre" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f1885697ee8a177096d42f158922251a41973117f6d8a234cee94b9509157b7" +dependencies = [ + "backtrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", +] + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" +dependencies = [ + "build_const", +] + +[[package]] +name = "crypto-mac" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "cryptohelpers" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9143447fb393f8d38abbb617af9b986a0941785ddc63685bd8de735fb31bcafc" +dependencies = [ + "base64 0.13.0", + "crc", + "futures", + "getrandom 0.1.16", + "hex-literal", + "hmac", + "libc", + "openssl", + "pbkdf2", + "serde", + "serde_derive", + "sha2", + "tokio 0.2.25", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "eyre" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221239d1d5ea86bf5d6f91c9d6bc3646ffe471b08ff9b0f91c44f115ac969d2b" +dependencies = [ + "indenter", + "once_cell", +] + +[[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 = "futures" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" + +[[package]] +name = "futures-executor" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" + +[[package]] +name = "futures-macro" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" + +[[package]] +name = "futures-task" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" + +[[package]] +name = "futures-util" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite 0.2.7", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" + +[[package]] +name = "half" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex-literal" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" + +[[package]] +name = "hmac" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deae6d9dbb35ec2c502d62b8f7b1c000a0822c3b0794ba36b3149c0a1c840dff" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "instant" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" +dependencies = [ + "cfg-if", +] + +[[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.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-sys" +version = "0.9.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "owo-colors" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "pbkdf2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170d73bf11f39b4ce1809aabc95bf5c33564cdc16fc3200ddda17a5f6e5e48b" +dependencies = [ + "base64 0.12.3", + "crypto-mac", + "hmac", + "rand", + "rand_core", + "sha2", + "subtle", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "tokio" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" +dependencies = [ + "bytes 0.5.6", + "memchr", + "pin-project-lite 0.1.12", +] + +[[package]] +name = "tokio" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc" +dependencies = [ + "autocfg", + "bytes 1.1.0", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite 0.2.7", + "signal-hook-registry", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "transfer" +version = "0.1.0" +dependencies = [ + "async-compression", + "base64 0.13.0", + "color-eyre", + "cryptohelpers", + "getrandom 0.2.3", + "lazy_static", + "log", + "openssl", + "pretty_env_logger", + "serde", + "serde_cbor", + "tokio 1.12.0", +] + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[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" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b9a0626 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "transfer" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-compression = { version = "0.3.8", features = ["tokio", "brotli"] } +base64 = "0.13.0" +color-eyre = { version = "0.5.11", default-features = false } +cryptohelpers = { version = "1.8.2", features = ["full"] } +getrandom = "0.2.3" +lazy_static = "1.4.0" +log = "0.4.14" +openssl = "0.10.36" +pretty_env_logger = "0.4.0" +serde = { version = "1.0.130", features = ["derive"] } +serde_cbor = "0.11.2" +tokio = { version = "1.12.0", features = ["full"] } diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..69ea705 --- /dev/null +++ b/src/args.rs @@ -0,0 +1,60 @@ +//! Arg parsing and process info +use super::*; +use std::fmt; + +lazy_static!{ + static ref EXEC: String = std::env::args().next().unwrap(); +} + +pub fn program_name() -> &'static str +{ + &EXEC[..] +} + +/// Program usage +#[derive(Debug)] +pub struct Usage; + +impl Usage +{ + pub fn print_and_exit(self, code: i32) -> ! + { + if code == 0 { + print!("{}", self); + } else { + eprint!("{}", self); + } + std::process::exit(code) + } +} + +fn splash(f: &mut fmt::Formatter<'_>) -> fmt::Result +{ + writeln!(f, "transfer v{} - simple network file transfer", env!("CARGO_PKG_VERSION"))?; + writeln!(f, " written by {} with <3. License GPL3+", env!("CARGO_PKG_AUTHORS"))?; + writeln!(f, "") +} + +impl fmt::Display for Usage +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + splash(f)?; + + writeln!(f, "Usage: {} --send [SEND OPTIONS] ", program_name())?; + writeln!(f, "Usage: {} --recv [RECV OPTIONS] ", program_name())?; + writeln!(f, "\nSEND OPTIONS:")?; + writeln!(f, " -e\t\t\tEncrypt file(s)")?; + writeln!(f, " -c\t\t\tCompress files")?; + writeln!(f, " --buffer-size \tSize of file buffer")?; + writeln!(f, " -a\t\t\tSend file names")?; + writeln!(f, " -1\t\t\tExit after 1 client has been served")?; + writeln!(f, " -k\t\t\tSupport continuation of failed downloads")?; + + writeln!(f, "\nRECV OPTIONS:")?; + writeln!(f, " -i\t\t\tAsk before starting downloads")?; + writeln!(f, " -k\t\t\tContinue a previously started download")?; + + Ok(()) + } +} diff --git a/src/cha.rs b/src/cha.rs new file mode 100644 index 0000000..30818dc --- /dev/null +++ b/src/cha.rs @@ -0,0 +1,40 @@ + +use openssl::{ + symm::{ + Cipher, Crypter, Mode, + }, + error::ErrorStack, +}; +use crate::key::{Key, IV}; + +/// Size of the key used for the cipher +pub const KEY_SIZE: usize = 32; +/// Size of the IV used for the cipher +pub const IV_SIZE: usize = 12; + +static NEW_CIPHER: fn() -> Cipher = Cipher::chacha20_poly1305; + +#[inline] pub fn decrypter(key: impl AsRef, iv: impl AsRef) -> Result +{ + Crypter::new( + NEW_CIPHER(), + Mode::Decrypt, + key.as_ref().as_ref(), + Some(iv.as_ref().as_ref()) + ) +} +#[inline] pub fn encrypter(key: impl AsRef, iv: impl AsRef) -> Result +{ + Crypter::new( + NEW_CIPHER(), + Mode::Encrypt, + key.as_ref().as_ref(), + Some(iv.as_ref().as_ref()) + ) +} + +/// Generate a random key and IV for the chacha20_poly1305 cipher +#[inline(always)] pub fn keygen() -> (Key, IV) +{ + (Key::new(), IV::new()) +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..cd3113a --- /dev/null +++ b/src/config.rs @@ -0,0 +1,61 @@ +//! Configuration +use super::*; + +pub const DEFAULT_BUFFER_SIZE: usize = 4096; + +/// Configuration for sending +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SendConfig +{ + encrypt: bool, + compress: bool, + buffer_size: usize, + archive: bool, + oneshot: bool, + continuation: bool, +} + +impl Default for SendConfig +{ + #[inline] + fn default() -> Self + { + Self { + encrypt: false, + compress: false, + buffer_size: DEFAULT_BUFFER_SIZE, + archive: false, + oneshot: false, + continuation: false, + } + } +} + +/// Configuration for receiving +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct RecvConfig +{ + interactive: bool, + continuation: bool, +} + +impl Default for RecvConfig +{ + #[inline] + fn default() -> Self + { + Self { + interactive: false, + continuation: false, + } + } +} + + +/// Program configuration +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Config +{ + Send(SendConfig), + Recv(RecvConfig), +} diff --git a/src/ext.rs b/src/ext.rs new file mode 100644 index 0000000..1c1f277 --- /dev/null +++ b/src/ext.rs @@ -0,0 +1,124 @@ +use std::{ + mem, + iter::{ + self, + ExactSizeIterator, + FusedIterator, + }, + slice, + fmt, +}; +#[derive(Debug, Clone)] +pub struct HexStringIter(I, [u8; 2]); + +impl> HexStringIter +{ + /// Write this hex string iterator to a formattable buffer + pub fn consume(self, f: &mut F) -> fmt::Result + where F: std::fmt::Write + { + if self.1[0] != 0 { + write!(f, "{}", self.1[0] as char)?; + } + if self.1[1] != 0 { + write!(f, "{}", self.1[1] as char)?; + } + + for x in self.0 { + write!(f, "{:02x}", x)?; + } + + Ok(()) + } + + /// Consume into a string + pub fn into_string(self) -> String + { + let mut output = match self.size_hint() { + (0, None) => String::new(), + (_, Some(x)) | + (x, None) => String::with_capacity(x), + }; + self.consume(&mut output).unwrap(); + output + } +} + +pub trait HexStringIterExt: Sized +{ + fn into_hex(self) -> HexStringIter; +} + +pub type HexStringSliceIter<'a> = HexStringIter>>; + +pub trait HexStringSliceIterExt +{ + fn hex(&self) -> HexStringSliceIter<'_>; +} + +impl HexStringSliceIterExt for S +where S: AsRef<[u8]> +{ + fn hex(&self) -> HexStringSliceIter<'_> + { + self.as_ref().iter().copied().into_hex() + } +} + +impl> HexStringIterExt for I +{ + #[inline] fn into_hex(self) -> HexStringIter { + HexStringIter(self.into_iter(), [0u8; 2]) + } +} + +impl> Iterator for HexStringIter +{ + type Item = char; + fn next(&mut self) -> Option + { + match self.1 { + [_, 0] => { + use std::io::Write; + write!(&mut self.1[..], "{:02x}", self.0.next()?).unwrap(); + + Some(mem::replace(&mut self.1[0], 0) as char) + }, + [0, _] => Some(mem::replace(&mut self.1[1], 0) as char), + _ => unreachable!(), + } + } + + fn size_hint(&self) -> (usize, Option) { + let (l, h) = self.0.size_hint(); + + (l * 2, h.map(|x| x*2)) + } +} + +impl + ExactSizeIterator> ExactSizeIterator for HexStringIter{} +impl + FusedIterator> FusedIterator for HexStringIter{} + +impl> From> for String +{ + fn from(from: HexStringIter) -> Self + { + from.into_string() + } +} + +impl + Clone> fmt::Display for HexStringIter +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + self.clone().consume(f) + } +} + +/* +#[macro_export] macro_rules! prog1 { + ($first:expr, $($rest:expr);+ $(;)?) => { + ($first, $( $rest ),+).0 + } +} +*/ diff --git a/src/key.rs b/src/key.rs new file mode 100644 index 0000000..007e509 --- /dev/null +++ b/src/key.rs @@ -0,0 +1,289 @@ +//! Key and IV structures for the cipher + +use getrandom::getrandom; +use std::{fmt, str}; +pub use crate::cha::{ + KEY_SIZE, + IV_SIZE, +}; +use crate::ext::*; + +/// A 32 byte key for the chacha20_poly1305 cipher +/// +/// # Generation +/// You can generate a random key with `Key::new()`. +/// To create a key structure from bytes, you can use `Key::from_bytes()` if the size of the buffer is exact, or you can write to an empty `Key` as it implements `Default`. +/// ``` +/// # use chacha20stream::{Key, key::KEY_SIZE}; +/// # let key_bytes = [0u8; 32]; +/// let mut key = Key::default(); +/// key.as_mut().copy_from_slice(&key_bytes[..KEY_SIZE]); +/// ``` +/// +/// You can also generate a random key/IV pair with `chacha20stream::keygen()`. +/// +/// # Encoding +/// This type implements `std::fmt::Display`, which prints the key as a base64 string. +/// Additionally, it implements `std::str::FromStr`, which decodes a base64 string into a `Key` instance. +/// If the input base64 string data decoded is shorter than `KEY_SIZE`, the rest of the key instance is padded with 0s. +/// If it is longer, the rest is ignored. +/// +/// The key can also be lazily formatted as a hex string, with the method `to_hex_string()`. +/// ``` +/// # use chacha20stream::Key; +/// let key = Key::new(); +/// let key_encoded = key.to_string(); +/// +/// println!("Key base64: {}", key_encoded); +/// println!("Key hex: {}", key.to_hex_string()); +/// +/// assert_eq!(key_encoded.parse::().unwrap(), key); +/// ``` +#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, Default)] +#[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))] +#[repr(transparent)] +pub struct Key([u8; KEY_SIZE]); + +/// A 12 byte IV for the chacha20_poly1305 cipher +/// +/// # Generation +/// You can generate a random IV with `IV::new()`. +/// To create an IV structure from bytes, you can use `IV::from_bytes()` if the size of the buffer is exact, or you can write to an empty `IV` as it implements `Default`. +/// ``` +/// # use chacha20stream::{IV, key::IV_SIZE}; +/// # let iv_bytes = [0u8; 12]; +/// let mut iv = IV::default(); +/// iv.as_mut().copy_from_slice(&iv_bytes[..IV_SIZE]); +/// ``` +/// +/// You can also generate a random key/IV pair with `chacha20stream::keygen()`. +/// +/// # Encoding +/// This type implements `std::fmt::Display`, which prints the IV as a base64 string. +/// Additionally, it implements `std::str::FromStr`, which decodes a base64 string into a `IV` instance. +/// If the input base64 string data decoded is shorter than `IV_SIZE`, the rest of the IV instance is padded with 0s. +/// If it is longer, the rest is ignored. +/// +/// The IV can also be lazily formatted as a hex string, with the method `to_hex_string()`. +/// ``` +/// # use chacha20stream::IV; +/// let iv = IV::new(); +/// let iv_encoded = iv.to_string(); +/// +/// println!("IV base64: {}", iv_encoded); +/// println!("IV hex: {}", iv.to_hex_string()); +/// +/// assert_eq!(iv_encoded.parse::().unwrap(), iv); +/// ``` +#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, Default)] +#[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))] +#[repr(transparent)] +pub struct IV([u8; IV_SIZE]); + +impl Key +{ + /// Construct a `Key` from an exact length (32 bytes) buffer. + #[inline] pub fn from_bytes(k: [u8; KEY_SIZE]) -> Self + { + Self(k) + } + /// Create a new random 32 byte chacha20_poly1305 `Key`. + pub fn new() -> Self + { + let mut output = [0u8; KEY_SIZE]; + getrandom(&mut output[..]).expect("rng fatal"); + Self(output) + } + + /// Format this key as a hex string + /// + /// Returns an opaque type that lazily formats the key into a hex string when written. + /// + /// # Example + /// ``` + /// # use chacha20stream::Key; + /// fn print_key_info(key: &Key) { + /// println!("Key base64: {}", key); + /// println!("Key hex: {}", key.to_hex_string()); + /// } + /// ``` + /// Formatting to `String` + /// ``` + /// # use chacha20stream::Key; + /// # let key = Key::new(); + /// let key_hex_string = key.to_hex_string().to_string(); + /// ``` + pub fn to_hex_string(&self) -> impl fmt::Display + '_ + { + self.0.iter().copied().into_hex() + } +} + +impl IV +{ + + /// Construct a `IV` from an exact length (12 bytes) buffer. + #[inline] pub fn from_bytes(k: [u8; IV_SIZE]) -> Self + { + Self(k) + } + /// Create a new random 12 byte chacha20_poly1305 `IV`. + pub fn new() -> Self + { + let mut output = [0u8; IV_SIZE]; + getrandom(&mut output[..]).expect("rng fatal"); + Self(output) + } + + /// Format this IV as a hex string + /// + /// Returns an opaque type that lazily formats the IV into a hex string when written. + /// + /// # Example + /// ``` + /// # use chacha20stream::IV; + /// fn print_iv_info(iv: &IV) { + /// println!("IV base64: {}", iv); + /// println!("IV hex: {}", iv.to_hex_string()); + /// } + /// ``` + /// Formatting to `String` + /// ``` + /// # use chacha20stream::IV; + /// # let iv = IV::new(); + /// let iv_hex_string = iv.to_hex_string().to_string(); + /// ``` + pub fn to_hex_string(&self) -> impl fmt::Display + '_ + { + self.0.iter().copied().into_hex() + } +} + +impl From<[u8; KEY_SIZE]> for Key +{ + #[inline] fn from(from: [u8; KEY_SIZE]) -> Self + { + Self(from) + } +} + +impl From<[u8; IV_SIZE]> for IV +{ + fn from(from: [u8; IV_SIZE]) -> Self + { + Self(from) + } +} + + +impl AsRef<[u8]> for Key +{ + fn as_ref(&self) -> &[u8] + { + &self.0[..] + } +} +impl AsRef<[u8]> for IV +{ + fn as_ref(&self) -> &[u8] + { + &self.0[..] + } +} + +impl AsMut<[u8]> for Key +{ + fn as_mut(&mut self) -> &mut [u8] + { + &mut self.0[..] + } +} + +impl AsMut<[u8]> for IV +{ + fn as_mut(&mut self) -> &mut [u8] + { + &mut self.0[..] + } +} + +impl AsRef for Key +{ + #[inline] fn as_ref(&self) -> &Key + { + self + } +} +impl AsRef for IV +{ + #[inline] fn as_ref(&self) -> &IV + { + self + } +} + +impl fmt::Display for Key +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + write!(f, "{}", base64::encode(&self.0[..])) + } +} + +impl fmt::Display for IV +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + write!(f, "{}", base64::encode(&self.0[..])) + } +} + +impl str::FromStr for Key +{ + type Err = base64::DecodeError; + + fn from_str(s: &str) -> Result { + let mut buffer = Vec::with_capacity(KEY_SIZE); + base64::decode_config_buf(s.as_bytes(), base64::STANDARD, &mut buffer)?; + + let mut this = Self::default(); + let sz = std::cmp::min(KEY_SIZE, buffer.len()); + (&mut this.0[..sz]).copy_from_slice(&buffer[..sz]); + Ok(this) + } +} + +impl str::FromStr for IV +{ + type Err = base64::DecodeError; + + fn from_str(s: &str) -> Result { + let mut buffer = Vec::with_capacity(IV_SIZE); + base64::decode_config_buf(s.as_bytes(), base64::STANDARD, &mut buffer)?; + + let mut this = Self::default(); + let sz = std::cmp::min(IV_SIZE, buffer.len()); + (&mut this.0[..sz]).copy_from_slice(&buffer[..sz]); + Ok(this) + } +} + +#[cfg(test)] +mod tests +{ + use super::{Key, IV}; + #[test] + fn enc_dec() + { + let (key, iv) = crate::keygen(); + + let key_str = key.to_string(); + let iv_str = iv.to_string(); + + let (key2, iv2): (Key, IV) = (key_str.parse().expect("key"), + iv_str.parse().expect("iv")); + + assert_eq!(key, key2); + assert_eq!(iv, iv2); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..98f785f --- /dev/null +++ b/src/main.rs @@ -0,0 +1,41 @@ + +#![allow(dead_code)] + +#[macro_use] extern crate log; +#[macro_use] extern crate lazy_static; +#[macro_use] extern crate serde; + +use color_eyre::{ + eyre::{ + self, + eyre, + WrapErr, + }, + SectionExt, Help, +}; + +mod ext; +mod key; +mod cha; + +mod config; +mod args; + +mod send; + +fn setup() -> eyre::Result<()> +{ + color_eyre::install()?; + pretty_env_logger::init(); + + Ok(()) +} + +#[tokio::main] +async fn main() -> eyre::Result<()> { + setup().wrap_err(eyre!("Failed to initialise logger"))?; + + args::Usage.print_and_exit(0); + + Ok(()) +} diff --git a/src/send/handshake.rs b/src/send/handshake.rs new file mode 100644 index 0000000..531b213 --- /dev/null +++ b/src/send/handshake.rs @@ -0,0 +1,20 @@ +//! Module handles setting up streams for files +use super::*; +use std::marker::Unpin; +use tokio::io::{ + AsyncRead, +}; + + +/// A read request from the client. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Request +{ + +} + +pub async fn read_req(mut from: T, key: ) -> eyre::Result +where T: AsyncRead + Unpin +{ + todo!("how do we handle encryption of the request data? eh... boring") +} diff --git a/src/send/mod.rs b/src/send/mod.rs new file mode 100644 index 0000000..0654d3a --- /dev/null +++ b/src/send/mod.rs @@ -0,0 +1,5 @@ +//! Sending + +use super::*; + +pub mod handshake;