From c62a12f369833293dadc326a3de0cd2e35c02537 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 2 Jul 2022 18:13:26 +0800 Subject: [PATCH 01/10] v0.1.0 init commit --- .gitignore | 4 +- Cargo.lock | 1183 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 15 + src/main.rs | 3 + 4 files changed, 1202 insertions(+), 3 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore index 3bf25c0..3a4c601 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,10 @@ +.idea/ # ---> Rust # Generated by Cargo # will have compiled files and executables debug/ target/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..4805be6 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1183 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "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 = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "buf_redux" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" +dependencies = [ + "memchr", + "safemem", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "h2" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util 0.7.3", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" + +[[package]] +name = "headers" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d" +dependencies = [ + "base64", + "bitflags", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha-1 0.10.0", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[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" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[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.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "local-mini-kms" +version = "0.1.0" +dependencies = [ + "hex", + "rust_util", + "serde", + "serde_derive", + "serde_json", + "tokio", + "warp", +] + +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "multipart" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" +dependencies = [ + "buf_redux", + "httparse", + "log", + "mime", + "mime_guess", + "quick-error", + "rand", + "safemem", + "tempfile", + "twoway", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "proc-macro2" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +dependencies = [ + "unicode-ident", +] + +[[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.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rust_util" +version = "0.6.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df24005feacce81f4ae340464b39c380f7e01e7225bfdef62d40cb44cb1c11d7" +dependencies = [ + "lazy_static", + "libc", + "term", + "term_size", +] + +[[package]] +name = "rustversion" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf" + +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[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.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.3", +] + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" + +[[package]] +name = "smallvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "term_size" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +dependencies = [ + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8" +dependencies = [ + "futures-util", + "log", + "pin-project", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "tungstenite" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" +dependencies = [ + "base64", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand", + "sha-1 0.9.8", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "twoway" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" +dependencies = [ + "memchr", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" + +[[package]] +name = "unicode-normalization" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "warp" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers", + "http", + "hyper", + "log", + "mime", + "mime_guess", + "multipart", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tokio-util 0.6.10", + "tower-service", + "tracing", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[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-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..8f7c784 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "local-mini-kms" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +hex = "0.4" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +rust_util = "0.6" +tokio = { version = "1.19", features = ["full"] } +serde_derive = "1.0" +warp = "0.3" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} -- 2.27.0 From 3c67fcb5bcd54be6125114169b3b4fad034315da Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 2 Jul 2022 18:37:22 +0800 Subject: [PATCH 02/10] feat: update clap --- Cargo.lock | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 +++-- src/main.rs | 42 +++++++++++++++++++++++++++++++++-- 3 files changed, 107 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4805be6..6de542a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,26 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -66,6 +86,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "cpufeatures" version = "0.2.2" @@ -388,6 +423,7 @@ checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" name = "local-mini-kms" version = "0.1.0" dependencies = [ + "clap", "hex", "rust_util", "serde", @@ -652,6 +688,7 @@ version = "0.6.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df24005feacce81f4ae340464b39c380f7e01e7225bfdef62d40cb44cb1c11d7" dependencies = [ + "clap", "lazy_static", "libc", "term", @@ -786,6 +823,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "syn" version = "1.0.98" @@ -832,6 +875,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.31" @@ -1047,6 +1099,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "url" version = "2.2.2" @@ -1065,6 +1123,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 8f7c784..ee96e1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clap = "2.33" hex = "0.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -rust_util = "0.6" +rust_util = { version = "0.6", features = ["use_clap"] } tokio = { version = "1.19", features = ["full"] } serde_derive = "1.0" -warp = "0.3" \ No newline at end of file +warp = "0.3" diff --git a/src/main.rs b/src/main.rs index e7a11a9..2bc38ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,41 @@ -fn main() { - println!("Hello, world!"); +use clap::{App, AppSettings, ArgMatches}; +use rust_util::{failure_and_exit, information}; +use rust_util::util_clap::{Command, CommandError}; + +pub struct DefaultCommandImpl; + +impl DefaultCommandImpl { + pub fn process_command<'a>(app: App<'a, 'a>) -> App<'a, 'a> { + app + } + pub fn run(_arg_matches: &ArgMatches) -> CommandError { + information!("Local mini KMS cli, use --help for help"); + Ok(None) + } } + +fn main() { + if let Err(e) = inner_main() { + failure_and_exit!("Run local-mini-kms error: {}", e); + } +} + +fn inner_main() -> CommandError { + let commands: Vec> = vec![]; + let mut app = App::new(env!("CARGO_PKG_NAME")) + .version(env!("CARGO_PKG_VERSION")) + .about(env!("CARGO_PKG_DESCRIPTION")) + .long_about("Local mini KMS") + .setting(AppSettings::ColoredHelp); + app = DefaultCommandImpl::process_command(app); + for command in &commands { + app = app.subcommand(command.subcommand()); + } + let matches = app.get_matches(); + for command in &commands { + if let Some(sub_cmd_matches) = matches.subcommand_matches(command.name()) { + return command.run(&matches, sub_cmd_matches); + } + } + DefaultCommandImpl::run(&matches) +} \ No newline at end of file -- 2.27.0 From 065d1a89a62c29450b8a5ea38ce4c53fde993f62 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 2 Jul 2022 18:50:01 +0800 Subject: [PATCH 03/10] feat: add subcommands cli, serve --- src/cli.rs | 18 ++++++++++++++++++ src/main.rs | 8 +++++++- src/serve.rs | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/cli.rs create mode 100644 src/serve.rs diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..e16ad8c --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,18 @@ +use clap::{App, Arg, ArgMatches, SubCommand}; +use rust_util::simple_error; +use rust_util::util_clap::{Command, CommandError}; + +pub struct CommandImpl; + +impl Command for CommandImpl { + fn name(&self) -> &str { "cli" } + + fn subcommand<'a>(&self) -> App<'a, 'a> { + SubCommand::with_name(self.name()).about("Local mini KMS cli") + .arg(Arg::with_name("connect").long("connect").takes_value(true).default_value("127.0.0.1:6567").help("Connect server")) + } + + fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { + simple_error!("Not implemented") + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 2bc38ee..97309b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,9 @@ use clap::{App, AppSettings, ArgMatches}; use rust_util::{failure_and_exit, information}; use rust_util::util_clap::{Command, CommandError}; +mod cli; +mod serve; + pub struct DefaultCommandImpl; impl DefaultCommandImpl { @@ -21,7 +24,10 @@ fn main() { } fn inner_main() -> CommandError { - let commands: Vec> = vec![]; + let commands: Vec> = vec![ + Box::new(cli::CommandImpl), + Box::new(serve::CommandImpl), + ]; let mut app = App::new(env!("CARGO_PKG_NAME")) .version(env!("CARGO_PKG_VERSION")) .about(env!("CARGO_PKG_DESCRIPTION")) diff --git a/src/serve.rs b/src/serve.rs new file mode 100644 index 0000000..bc6aa6c --- /dev/null +++ b/src/serve.rs @@ -0,0 +1,18 @@ +use clap::{App, Arg, ArgMatches, SubCommand}; +use rust_util::simple_error; +use rust_util::util_clap::{Command, CommandError}; + +pub struct CommandImpl; + +impl Command for CommandImpl { + fn name(&self) -> &str { "serve" } + + fn subcommand<'a>(&self) -> App<'a, 'a> { + SubCommand::with_name(self.name()).about("Local mini KMS serve") + .arg(Arg::with_name("listen").long("listen").takes_value(true).default_value("127.0.0.1:6567").help("Listen")) + } + + fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { + simple_error!("Not implemented") + } +} \ No newline at end of file -- 2.27.0 From 038d5546e012936aaaf6e23fb53bc587b4046e8a Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 24 Jul 2022 02:10:13 +0800 Subject: [PATCH 04/10] feat: building --- Cargo.lock | 550 ++++++--------------------------------------------- Cargo.toml | 6 +- src/cli.rs | 4 +- src/db.rs | 27 +++ src/main.rs | 1 + src/serve.rs | 78 +++++++- 6 files changed, 171 insertions(+), 495 deletions(-) create mode 100644 src/db.rs diff --git a/Cargo.lock b/Cargo.lock index 6de542a..9015d5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -28,52 +39,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - [[package]] name = "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 = "block-buffer" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" -dependencies = [ - "generic-array", -] - -[[package]] -name = "buf_redux" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" -dependencies = [ - "memchr", - "safemem", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "bytes" version = "1.1.0" @@ -101,44 +72,6 @@ dependencies = [ "vec_map", ] -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer 0.10.2", - "crypto-common", -] - [[package]] name = "dirs-next" version = "2.0.0" @@ -161,13 +94,16 @@ dependencies = [ ] [[package]] -name = "fastrand" -version = "1.7.0" +name = "fallible-iterator" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fnv" @@ -175,16 +111,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - [[package]] name = "futures-channel" version = "0.3.21" @@ -192,7 +118,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -220,21 +145,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-core", - "futures-sink", "futures-task", "pin-project-lite", "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", ] [[package]] @@ -263,39 +176,26 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.3", + "tokio-util", "tracing", ] [[package]] name = "hashbrown" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" - -[[package]] -name = "headers" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "base64", - "bitflags", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha-1 0.10.0", + "ahash", ] [[package]] -name = "headers-core" -version = "0.2.0" +name = "hashlink" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +checksum = "d452c155cb93fecdfb02a73dd57b5d8e442c2063bd7aac72f1bc5e4263a43086" dependencies = [ - "http", + "hashbrown", ] [[package]] @@ -349,9 +249,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.19" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -371,17 +271,6 @@ dependencies = [ "want", ] -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "indexmap" version = "1.9.1" @@ -392,15 +281,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - [[package]] name = "itoa" version = "1.0.2" @@ -419,18 +299,30 @@ version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +[[package]] +name = "libsqlite3-sys" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f0455f2c1bc9a7caa792907026e469c1d91761fb0ea37cbb16427c77280cf35" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "local-mini-kms" version = "0.1.0" dependencies = [ "clap", "hex", + "hyper", + "lazy_static", + "rusqlite", "rust_util", "serde", "serde_derive", "serde_json", "tokio", - "warp", ] [[package]] @@ -452,34 +344,12 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "mio" version = "0.8.4" @@ -492,24 +362,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "multipart" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" -dependencies = [ - "buf_redux", - "httparse", - "log", - "mime", - "mime_guess", - "quick-error", - "rand", - "safemem", - "tempfile", - "twoway", -] - [[package]] name = "num_cpus" version = "1.13.1" @@ -526,12 +378,6 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "parking_lot" version = "0.12.1" @@ -555,32 +401,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pin-project" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "pin-project-lite" version = "0.2.9" @@ -594,10 +414,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "ppv-lite86" -version = "0.2.16" +name = "pkg-config" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "proc-macro2" @@ -608,12 +428,6 @@ dependencies = [ "unicode-ident", ] -[[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.20" @@ -623,36 +437,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - [[package]] name = "redox_syscall" version = "0.2.13" @@ -674,12 +458,17 @@ dependencies = [ ] [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "rusqlite" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" dependencies = [ - "winapi", + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", ] [[package]] @@ -707,18 +496,6 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - -[[package]] -name = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - [[package]] name = "scopeguard" version = "1.1.0" @@ -756,42 +533,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha-1" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.3", -] - [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -803,9 +544,12 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" @@ -840,20 +584,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - [[package]] name = "term" version = "0.7.0" @@ -904,21 +634,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - [[package]] name = "tokio" version = "1.19.2" @@ -950,44 +665,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tokio-stream" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8" -dependencies = [ - "futures-util", - "log", - "pin-project", - "tokio", - "tungstenite", -] - -[[package]] -name = "tokio-util" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-util" version = "0.7.3" @@ -1015,7 +692,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ "cfg-if", - "log", "pin-project-lite", "tracing-core", ] @@ -1035,70 +711,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" -[[package]] -name = "tungstenite" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" -dependencies = [ - "base64", - "byteorder", - "bytes", - "http", - "httparse", - "log", - "rand", - "sha-1 0.9.8", - "thiserror", - "url", - "utf-8", -] - -[[package]] -name = "twoway" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" -dependencies = [ - "memchr", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" - [[package]] name = "unicode-ident" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" -[[package]] -name = "unicode-normalization" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-width" version = "0.1.9" @@ -1106,22 +724,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] -name = "url" -version = "2.2.2" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" @@ -1145,36 +751,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "warp" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "headers", - "http", - "hyper", - "log", - "mime", - "mime_guess", - "multipart", - "percent-encoding", - "pin-project", - "scoped-tls", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-stream", - "tokio-tungstenite", - "tokio-util 0.6.10", - "tower-service", - "tracing", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index ee96e1a..b13a612 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,11 @@ edition = "2021" [dependencies] clap = "2.33" hex = "0.4" +lazy_static = "1.4.0" +serde_derive = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rust_util = { version = "0.6", features = ["use_clap"] } tokio = { version = "1.19", features = ["full"] } -serde_derive = "1.0" -warp = "0.3" +hyper = { version = "0.14.20", features = ["client", "server", "tcp", "http1", "http2"] } +rusqlite = "0.28.0" diff --git a/src/cli.rs b/src/cli.rs index e16ad8c..fb60d75 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -6,13 +6,13 @@ pub struct CommandImpl; impl Command for CommandImpl { fn name(&self) -> &str { "cli" } - + fn subcommand<'a>(&self) -> App<'a, 'a> { SubCommand::with_name(self.name()).about("Local mini KMS cli") .arg(Arg::with_name("connect").long("connect").takes_value(true).default_value("127.0.0.1:6567").help("Connect server")) } - fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { + fn run(&self, _arg_matches: &ArgMatches, _sub_arg_matches: &ArgMatches) -> CommandError { simple_error!("Not implemented") } } \ No newline at end of file diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..001d7d8 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,27 @@ +use rusqlite::{Connection, params}; +use rust_util::{debugging, information, opt_result, success, XResult}; + +pub fn open_db(db: &str) -> XResult { + let con = opt_result!(Connection::open(db), "Open sqlite db: {}, failed: {}", db); + debugging!("Db auto commit: {}", con.is_autocommit()); + Ok(con) +} + +pub fn init_db(conn: &Connection) -> XResult { + let mut stmt = conn.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='keys'")?; + let mut rows = stmt.query(())?; + if rows.next()?.is_some() { + information!("Table keys exists, skip init"); + return Ok(false); + } + + let _ = conn.execute(r##" + CREATE TABLE keys ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + value TEXT + ) + "##, ())?; + success!("Table keys created"); + Ok(true) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 97309b9..341eade 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use clap::{App, AppSettings, ArgMatches}; use rust_util::{failure_and_exit, information}; use rust_util::util_clap::{Command, CommandError}; +mod db; mod cli; mod serve; diff --git a/src/serve.rs b/src/serve.rs index bc6aa6c..ad02f0b 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -1,6 +1,16 @@ +use std::sync::RwLock; use clap::{App, Arg, ArgMatches, SubCommand}; -use rust_util::simple_error; +use hyper::{Body, Client, Method, Request, Response, Server, StatusCode}; +use hyper::client::HttpConnector; +use hyper::service::{make_service_fn, service_fn}; +use rust_util::{failure_and_exit, iff, information, success}; use rust_util::util_clap::{Command, CommandError}; +use crate::db; + +type GenericError = Box; +type Result = std::result::Result; + +static NOTFOUND: &[u8] = b"Not Found\n"; pub struct CommandImpl; @@ -9,10 +19,70 @@ impl Command for CommandImpl { fn subcommand<'a>(&self) -> App<'a, 'a> { SubCommand::with_name(self.name()).about("Local mini KMS serve") - .arg(Arg::with_name("listen").long("listen").takes_value(true).default_value("127.0.0.1:6567").help("Listen")) + .arg(Arg::with_name("listen").long("listen").takes_value(true).default_value("127.0.0.1:5567").help("Listen")) } fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { - simple_error!("Not implemented") + let listen = sub_arg_matches.value_of("listen").expect("Get argument listen error"); + let rt = tokio::runtime::Runtime::new().expect("Create tokio runtime error"); + rt.block_on(async { + let addr = listen.parse().expect(&format!("Parse listen error: {}", listen)); + let client = Client::new(); + let new_service = make_service_fn(move |_| { + let client = client.clone(); + async { + Ok::<_, GenericError>(service_fn(move |req| { + response_requests(req, client.to_owned()) + })) + } + }); + let server = Server::bind(&addr).serve(new_service); + information!("Listening on http://{}", addr); + match server.await { + Err(e) => failure_and_exit!("Server error: {}", e), + Ok(_) => success!("Server ended"), + } + }); + Ok(Some(0)) } -} \ No newline at end of file +} + +// ref: https://github.com/hyperium/hyper/blob/master/examples/web_api.rs +async fn response_requests( + req: Request, + _client: Client, +) -> Result> { + match (req.method(), req.uri().path()) { + // (&Method::GET, "/") | (&Method::GET, "/index.html") => Ok(Response::new(INDEX.into())), + // (&Method::GET, "/test.html") => client_request_response(&client).await, + (&Method::GET, "/status") => status().await, + (&Method::GET, "/version") => get_version().await, + _ => { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND).body(NOTFOUND.into()) + .expect("Response not found error")) + } + } +} + +// ------------------------------------------------------------------------------------------------- + +struct MemoryKey { + master_key: Vec, +} + +lazy_static::lazy_static! { + static ref STATUS_RW_LOCK: RwLock = RwLock::new(false); +} + +async fn status() -> Result> { + let status_rw_lock = STATUS_RW_LOCK.read().expect("Lock read status rw lock error"); + let status_rw_lock_value = *status_rw_lock; + Ok(Response::builder().body(format!("{}\n", iff!(status_rw_lock_value, "init", "uninit")).into()).expect("x")) +} + +async fn get_version() -> Result> { + Ok(Response::builder().body(format!( + "{} - {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION") + ).into()).expect("Response get_version error")) +} -- 2.27.0 From 0b97850f654e0a02ad1be56206a806ecf32f34e5 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 24 Jul 2022 15:57:53 +0800 Subject: [PATCH 05/10] feat: update local-mini-kms --- Cargo.lock | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + src/db.rs | 32 +++++++++- src/jose.rs | 57 +++++++++++++++++ src/main.rs | 1 + src/serve.rs | 134 ++++++++++++++++++++++++++++++++++----- 6 files changed, 381 insertions(+), 17 deletions(-) create mode 100644 src/jose.rs diff --git a/Cargo.lock b/Cargo.lock index 9015d5b..ccc05b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.7.6" @@ -13,6 +19,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -22,6 +37,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "anyhow" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" + [[package]] name = "atty" version = "0.2.14" @@ -39,6 +60,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "bitflags" version = "1.3.2" @@ -51,6 +78,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + [[package]] name = "cfg-if" version = "1.0.0" @@ -72,6 +105,15 @@ dependencies = [ "vec_map", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -105,12 +147,37 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +[[package]] +name = "flate2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +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 = "futures-channel" version = "0.3.21" @@ -287,6 +354,24 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +[[package]] +name = "josekit" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee6af62ad98bdf699ad2ecc8323479a1fdc7aa5faa6043d93119d83f6c5fca8" +dependencies = [ + "anyhow", + "base64", + "flate2", + "once_cell", + "openssl", + "regex", + "serde", + "serde_json", + "thiserror", + "time", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -313,9 +398,11 @@ dependencies = [ name = "local-mini-kms" version = "0.1.0" dependencies = [ + "base64", "clap", "hex", "hyper", + "josekit", "lazy_static", "rusqlite", "rust_util", @@ -350,6 +437,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "miniz_oxide" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.4" @@ -372,12 +468,60 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "once_cell" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +[[package]] +name = "openssl" +version = "0.10.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-sys" +version = "0.9.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -457,6 +601,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regex" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" + [[package]] name = "rusqlite" version = "0.28.0" @@ -528,6 +689,7 @@ version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ + "indexmap", "itoa", "ryu", "serde", @@ -634,6 +796,16 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" +dependencies = [ + "libc", + "num_threads", +] + [[package]] name = "tokio" version = "1.19.2" diff --git a/Cargo.toml b/Cargo.toml index b13a612..c0da46f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,10 +8,12 @@ edition = "2021" [dependencies] clap = "2.33" hex = "0.4" +base64 = "0.13.0" lazy_static = "1.4.0" serde_derive = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +josekit = "0.8.1" rust_util = { version = "0.6", features = ["use_clap"] } tokio = { version = "1.19", features = ["full"] } hyper = { version = "0.14.20", features = ["client", "server", "tcp", "http1", "http2"] } diff --git a/src/db.rs b/src/db.rs index 001d7d8..992c6c9 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,5 +1,12 @@ use rusqlite::{Connection, params}; -use rust_util::{debugging, information, opt_result, success, XResult}; +use rust_util::{debugging, information, opt_result, simple_error, success, XResult}; + +pub const DEFAULT_MASTER_KEY_VERIFICATION_KEY: &'static str = "__master_verification_key"; + +pub struct Key { + name: String, + encrypted_key: String, +} pub fn open_db(db: &str) -> XResult { let con = opt_result!(Connection::open(db), "Open sqlite db: {}, failed: {}", db); @@ -24,4 +31,27 @@ pub fn init_db(conn: &Connection) -> XResult { "##, ())?; success!("Table keys created"); Ok(true) +} + +pub fn insert_key(conn: &Connection, key: &Key) -> XResult<()> { + let _ = conn.execute( + "INSERT INTO keys (name, value) VALUES (?1, ?2)", + (&key.name, &key.encrypted_key), + )?; + Ok(()) +} + +pub fn find_key(conn: &Connection, name: &str) -> XResult> { + let mut stmt = conn.prepare("SELECT id, name, value FROM keys WHERE name = ?1")?; + let mut key_iter = stmt.query_map(params![name], |row| { + Ok(Key { + name: row.get(1)?, + encrypted_key: row.get(2)?, + }) + })?; + match key_iter.next() { + None => Ok(None), + Some(Ok(r)) => Ok(Some(r)), + Some(Err(e)) => simple_error!("Find key failed: {}", e), + } } \ No newline at end of file diff --git a/src/jose.rs b/src/jose.rs new file mode 100644 index 0000000..326e63f --- /dev/null +++ b/src/jose.rs @@ -0,0 +1,57 @@ +use josekit::jwe; +use josekit::jwe::alg::aeskw::AeskwJweAlgorithm; +use josekit::jwe::alg::rsaes::RsaesJweAlgorithm; +use josekit::jwe::JweHeader; +use josekit::jwk::{Jwk, KeyPair}; +use josekit::jwk::alg::rsa::RsaKeyPair; +use rust_util::XResult; + +pub fn generate_rsa_key(bits: u32) -> XResult { + Ok(RsaKeyPair::generate(bits)?) +} + +pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult { + let mut header = JweHeader::new(); + header.set_content_encryption("A256GCM"); + let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?; + Ok(jwe::serialize_compact(payload, &header, &encrypter)?) +} + +pub fn deserialize_jwe_rsa(jwe: &str, jwk: &Jwk) -> XResult<(Vec, JweHeader)> { + let decrypter = RsaesJweAlgorithm::RsaOaep.decrypter_from_jwk(jwk)?; + Ok(jwe::deserialize_json(jwe, &decrypter)?) +} + +pub fn serialize_jwe_aes(payload: &[u8], key: &[u8]) -> XResult { + let mut header = JweHeader::new(); + header.set_content_encryption("A256GCM"); + let encrypter = AeskwJweAlgorithm::A256kw.encrypter_from_bytes(key)?; + Ok(jwe::serialize_compact(payload, &header, &encrypter)?) +} + +pub fn deserialize_jwe_aes(jwe: &str, key: &[u8]) -> XResult<(Vec, JweHeader)> { + let decrypter = AeskwJweAlgorithm::A192kw.decrypter_from_bytes(key)?; + Ok(jwe::deserialize_json(jwe, &decrypter)?) +} + +#[test] +fn a() { + let k = generate_rsa_key(4096).unwrap(); + let k = k.to_jwk_key_pair(); + let kk = k.to_public_key().unwrap(); + + println!("{:?}", k); + println!("{:?}", kk); + + let mut header = JweHeader::new(); + header.set_content_encryption("A256GCM"); + let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&kk).unwrap(); + let payload = "helloworld"; + let r = jwe::serialize_compact(payload.as_bytes(), &header, &encrypter); + + println!("{:?}", r); + + let k = "abcdefghijklmnopqrstuvwxyz123456"; + let t = serialize_jwe_aes(payload.as_bytes(), k.as_bytes()); + println!("{:?}", t); +} diff --git a/src/main.rs b/src/main.rs index 341eade..4015375 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use rust_util::{failure_and_exit, information}; use rust_util::util_clap::{Command, CommandError}; mod db; +mod jose; mod cli; mod serve; diff --git a/src/serve.rs b/src/serve.rs index ad02f0b..cbf8891 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -1,11 +1,17 @@ use std::sync::RwLock; + use clap::{App, Arg, ArgMatches, SubCommand}; -use hyper::{Body, Client, Method, Request, Response, Server, StatusCode}; +use hyper::{Body, Client, header, Method, Request, Response, Server, StatusCode}; +use hyper::body::Buf; use hyper::client::HttpConnector; use hyper::service::{make_service_fn, service_fn}; -use rust_util::{failure_and_exit, iff, information, success}; +use josekit::jwk::alg::rsa::RsaKeyPair; +use rust_util::{failure_and_exit, iff, information, success, XResult}; use rust_util::util_clap::{Command, CommandError}; -use crate::db; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; + +use crate::jose; type GenericError = Box; type Result = std::result::Result; @@ -23,6 +29,12 @@ impl Command for CommandImpl { } fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { + match init_instance() { + Ok(true) => success!("Init server success"), + Ok(false) => failure_and_exit!("SHOULD NOT HAPPEN, server already init"), + Err(e) => failure_and_exit!("Init server failed: {}", e), + } + let listen = sub_arg_matches.value_of("listen").expect("Get argument listen error"); let rt = tokio::runtime::Runtime::new().expect("Create tokio runtime error"); rt.block_on(async { @@ -48,41 +60,131 @@ impl Command for CommandImpl { } // ref: https://github.com/hyperium/hyper/blob/master/examples/web_api.rs +// ref: https://crates.io/crates/rusqlite async fn response_requests( req: Request, _client: Client, ) -> Result> { match (req.method(), req.uri().path()) { - // (&Method::GET, "/") | (&Method::GET, "/index.html") => Ok(Response::new(INDEX.into())), - // (&Method::GET, "/test.html") => client_request_response(&client).await, + (&Method::POST, "/init") => init(req).await, + (&Method::POST, "/decrypt") => decrypt(req).await, + (&Method::POST, "/encrypt") => encrypt(req).await, (&Method::GET, "/status") => status().await, (&Method::GET, "/version") => get_version().await, - _ => { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND).body(NOTFOUND.into()) - .expect("Response not found error")) - } + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND).body(NOTFOUND.into())?), } } // ------------------------------------------------------------------------------------------------- struct MemoryKey { - master_key: Vec, + instance_rsa_key_pair: RsaKeyPair, + master_key: Option>, } lazy_static::lazy_static! { - static ref STATUS_RW_LOCK: RwLock = RwLock::new(false); + static ref STATUP_RW_LOCK: RwLock> = RwLock::new(None); +} + +fn init_instance() -> XResult { + let mut startup_rw_lock = STATUP_RW_LOCK.write().expect("Lock write startup rw lock error"); + match &*startup_rw_lock { + Some(_) => Ok(false), + None => { + let memory_key = MemoryKey { + instance_rsa_key_pair: jose::generate_rsa_key(4096)?, + master_key: None, + }; + *startup_rw_lock = Some(memory_key); + Ok(true) + } + } +} + +async fn decrypt(req: Request) -> Result> { + let whole_body = hyper::body::aggregate(req).await?; + let data: serde_json::Value = serde_json::from_reader(whole_body.reader())?; + Ok(Response::builder().body(format!("{}", data).into())?) +} + +async fn encrypt(req: Request) -> Result> { + let whole_body = hyper::body::aggregate(req).await?; + let data: serde_json::Value = serde_json::from_reader(whole_body.reader())?; + Ok(Response::builder().body(format!("{}", data).into())?) +} + +#[derive(Serialize, Deserialize)] +struct InitRequest { + clear_master_key_hex: Option, + clear_master_key_base64: Option, + encrypted_master_key: Option, +} + +async fn init(req: Request) -> Result> { + let whole_body = hyper::body::aggregate(req).await?; + let init_request: InitRequest = serde_json::from_reader(whole_body.reader())?; + + let mut startup_rw_lock = STATUP_RW_LOCK.write().expect("Lock read startup rw lock error"); + let (status_code, body) = match &*startup_rw_lock { + None => (StatusCode::INTERNAL_SERVER_ERROR, json!({ "error": "internal_error", "error_message": "not init " })), + Some(memory_key) => match memory_key.master_key { + Some(_) => (StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "already init " })), + None => (StatusCode::OK, Value::Null), + }, + }; + if status_code != StatusCode::OK { + return Ok(Response::builder().status(status_code).body(serde_json::to_string_pretty(&body)?.into())?); + } + + let (status_code, body) = if let Some(clear_master_key_base64) = init_request.clear_master_key_base64 { + let clear_master_key = base64::decode(clear_master_key_base64)?; + if clear_master_key.len() != 32 { + (StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "bad clear_master_key_hex length" })) + } else { + if let Some(k) = &mut *startup_rw_lock { + k.master_key = Some(clear_master_key); + } + (StatusCode::OK, json!({})) + } + } else if let Some(clear_master_key_hex) = init_request.clear_master_key_hex { + let clear_master_key = hex::decode(clear_master_key_hex)?; + if clear_master_key.len() != 32 { + (StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "bad clear_master_key_hex length" })) + } else { + if let Some(k) = &mut *startup_rw_lock { + k.master_key = Some(clear_master_key); + } + (StatusCode::OK, json!({})) + } + } else if let Some(encrypted_master_key) = init_request.encrypted_master_key { + // TODO ... + (StatusCode::BAD_REQUEST, json!({ "error": "not_implement", "error_message": "not_implement" })) + } else { + (StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "master key is not provided" })) + }; + Ok(Response::builder().status(status_code).body(serde_json::to_string_pretty(&body)?.into())?) } async fn status() -> Result> { - let status_rw_lock = STATUS_RW_LOCK.read().expect("Lock read status rw lock error"); - let status_rw_lock_value = *status_rw_lock; - Ok(Response::builder().body(format!("{}\n", iff!(status_rw_lock_value, "init", "uninit")).into()).expect("x")) + let startup_rw_lock = STATUP_RW_LOCK.read().expect("Lock read startup rw lock error"); + let body = match &*startup_rw_lock { + None => json!({ "status": "n/a" }), + Some(memory_key) => match memory_key.master_key { + None => json!({ + "status": "not-ready", + "instance_public_key_jwk": memory_key.instance_rsa_key_pair.to_jwk_key_pair().to_public_key()?, + }), + Some(_) => json!({ + "status": "ready", + "instance_public_key_jwk": memory_key.instance_rsa_key_pair.to_jwk_key_pair().to_public_key()?, + }), + } + }; + Ok(Response::builder().body(serde_json::to_string_pretty(&body)?.into())?) } async fn get_version() -> Result> { Ok(Response::builder().body(format!( "{} - {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION") - ).into()).expect("Response get_version error")) + ).into())?) } -- 2.27.0 From ee0c59bbcfb128231ddf337452d2ea086a72916b Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 24 Jul 2022 17:55:08 +0800 Subject: [PATCH 06/10] feat: encrypt works --- .gitignore | 1 + Cargo.lock | 7 +++ Cargo.toml | 1 + src/db.rs | 4 +- src/jose.rs | 40 +++--------- src/serve.rs | 172 +++++++++++++++++++++++++++++++++++++++------------ 6 files changed, 151 insertions(+), 74 deletions(-) diff --git a/.gitignore b/.gitignore index 3a4c601..ea846e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +local-mini-kms.db .idea/ # ---> Rust # Generated by Cargo diff --git a/Cargo.lock b/Cargo.lock index ccc05b4..77a55c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,6 +410,7 @@ dependencies = [ "serde_derive", "serde_json", "tokio", + "zeroize", ] [[package]] @@ -993,3 +994,9 @@ name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "zeroize" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" diff --git a/Cargo.toml b/Cargo.toml index c0da46f..b03e4f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +zeroize = "1.5.7" clap = "2.33" hex = "0.4" base64 = "0.13.0" diff --git a/src/db.rs b/src/db.rs index 992c6c9..adda78a 100644 --- a/src/db.rs +++ b/src/db.rs @@ -4,8 +4,8 @@ use rust_util::{debugging, information, opt_result, simple_error, success, XResu pub const DEFAULT_MASTER_KEY_VERIFICATION_KEY: &'static str = "__master_verification_key"; pub struct Key { - name: String, - encrypted_key: String, + pub name: String, + pub encrypted_key: String, } pub fn open_db(db: &str) -> XResult { diff --git a/src/jose.rs b/src/jose.rs index 326e63f..0688a1d 100644 --- a/src/jose.rs +++ b/src/jose.rs @@ -2,20 +2,20 @@ use josekit::jwe; use josekit::jwe::alg::aeskw::AeskwJweAlgorithm; use josekit::jwe::alg::rsaes::RsaesJweAlgorithm; use josekit::jwe::JweHeader; -use josekit::jwk::{Jwk, KeyPair}; use josekit::jwk::alg::rsa::RsaKeyPair; +use josekit::jwk::Jwk; use rust_util::XResult; pub fn generate_rsa_key(bits: u32) -> XResult { Ok(RsaKeyPair::generate(bits)?) } -pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult { - let mut header = JweHeader::new(); - header.set_content_encryption("A256GCM"); - let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?; - Ok(jwe::serialize_compact(payload, &header, &encrypter)?) -} +// pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult { +// let mut header = JweHeader::new(); +// header.set_content_encryption("A256GCM"); +// let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?; +// Ok(jwe::serialize_compact(payload, &header, &encrypter)?) +// } pub fn deserialize_jwe_rsa(jwe: &str, jwk: &Jwk) -> XResult<(Vec, JweHeader)> { let decrypter = RsaesJweAlgorithm::RsaOaep.decrypter_from_jwk(jwk)?; @@ -30,28 +30,6 @@ pub fn serialize_jwe_aes(payload: &[u8], key: &[u8]) -> XResult { } pub fn deserialize_jwe_aes(jwe: &str, key: &[u8]) -> XResult<(Vec, JweHeader)> { - let decrypter = AeskwJweAlgorithm::A192kw.decrypter_from_bytes(key)?; - Ok(jwe::deserialize_json(jwe, &decrypter)?) -} - -#[test] -fn a() { - let k = generate_rsa_key(4096).unwrap(); - let k = k.to_jwk_key_pair(); - let kk = k.to_public_key().unwrap(); - - println!("{:?}", k); - println!("{:?}", kk); - - let mut header = JweHeader::new(); - header.set_content_encryption("A256GCM"); - let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&kk).unwrap(); - let payload = "helloworld"; - let r = jwe::serialize_compact(payload.as_bytes(), &header, &encrypter); - - println!("{:?}", r); - - let k = "abcdefghijklmnopqrstuvwxyz123456"; - let t = serialize_jwe_aes(payload.as_bytes(), k.as_bytes()); - println!("{:?}", t); + let decrypter = AeskwJweAlgorithm::A256kw.decrypter_from_bytes(key)?; + Ok(jwe::deserialize_compact(jwe, &decrypter)?) } diff --git a/src/serve.rs b/src/serve.rs index cbf8891..57b61af 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -1,22 +1,24 @@ use std::sync::RwLock; use clap::{App, Arg, ArgMatches, SubCommand}; -use hyper::{Body, Client, header, Method, Request, Response, Server, StatusCode}; +use hyper::{Body, Client, Method, Request, Response, Server, StatusCode}; use hyper::body::Buf; use hyper::client::HttpConnector; use hyper::service::{make_service_fn, service_fn}; use josekit::jwk::alg::rsa::RsaKeyPair; -use rust_util::{failure_and_exit, iff, information, success, XResult}; +use josekit::jwk::KeyPair; +use rust_util::{debugging, failure_and_exit, information, opt_result, opt_value_result, simple_error, success, XResult}; use rust_util::util_clap::{Command, CommandError}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; +use zeroize::Zeroize; -use crate::jose; +use crate::{db, jose}; +use crate::db::Key; type GenericError = Box; type Result = std::result::Result; -static NOTFOUND: &[u8] = b"Not Found\n"; pub struct CommandImpl; @@ -26,10 +28,12 @@ impl Command for CommandImpl { fn subcommand<'a>(&self) -> App<'a, 'a> { SubCommand::with_name(self.name()).about("Local mini KMS serve") .arg(Arg::with_name("listen").long("listen").takes_value(true).default_value("127.0.0.1:5567").help("Listen")) + .arg(Arg::with_name("local-db").long("local-db").takes_value(true).default_value("local-mini-kms.db").help("Local db file")) } fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { - match init_instance() { + let local_mini_kms_db = sub_arg_matches.value_of("local-db").expect("Get local mini kms db error"); + match init_instance(local_mini_kms_db) { Ok(true) => success!("Init server success"), Ok(false) => failure_and_exit!("SHOULD NOT HAPPEN, server already init"), Err(e) => failure_and_exit!("Init server failed: {}", e), @@ -71,13 +75,26 @@ async fn response_requests( (&Method::POST, "/encrypt") => encrypt(req).await, (&Method::GET, "/status") => status().await, (&Method::GET, "/version") => get_version().await, - _ => Ok(Response::builder().status(StatusCode::NOT_FOUND).body(NOTFOUND.into())?), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND).body(serde_json::to_string_pretty(&json!({ "error": "not_found" }))?.into())?), } } +macro_rules! do_response { + ($ex: expr) => ( + match $ex { + Ok((status_code, body)) => Ok(Response::builder().status(status_code).body(serde_json::to_string_pretty(&body)?.into())?), + Err(e) => Ok(Response::builder().status(StatusCode::INTERNAL_SERVER_ERROR).body(serde_json::to_string_pretty(&json!({ + "error": "internal_error", + "error_message": format!("{}", e), + }))?.into())?), + } + ) +} + // ------------------------------------------------------------------------------------------------- struct MemoryKey { + database_file: String, instance_rsa_key_pair: RsaKeyPair, master_key: Option>, } @@ -86,12 +103,16 @@ lazy_static::lazy_static! { static ref STATUP_RW_LOCK: RwLock> = RwLock::new(None); } -fn init_instance() -> XResult { +fn init_instance(db: &str) -> XResult { + let conn = db::open_db(db)?; + db::init_db(&conn)?; + let mut startup_rw_lock = STATUP_RW_LOCK.write().expect("Lock write startup rw lock error"); match &*startup_rw_lock { Some(_) => Ok(false), None => { let memory_key = MemoryKey { + database_file: db.to_string(), instance_rsa_key_pair: jose::generate_rsa_key(4096)?, master_key: None, }; @@ -101,6 +122,37 @@ fn init_instance() -> XResult { } } +#[derive(Serialize, Deserialize)] +struct MultipleViewValue { + value: Option, + value_hex: Option, + value_base64: Option, +} + +impl MultipleViewValue { + fn from(v: &[u8]) -> Self { + Self { + value: Some(String::from_utf8_lossy(v).to_string()), + value_hex: Some(hex::encode(v)), + value_base64: Some(base64::encode(v)), + } + } + + fn to_bytes(&self) -> XResult> { + if let Some(v) = &self.value { + Ok(v.as_bytes().to_vec()) + } else if let Some(v) = &self.value_hex { + let v = opt_result!(hex::decode(v), "Decode hex failed: {}"); + Ok(v) + } else if let Some(v) = &self.value_base64 { + let v = opt_result!(base64::decode(v), "Decode base64 failed: {}"); + Ok(v) + } else { + simple_error!("Multiple view value is all empty") + } + } +} + async fn decrypt(req: Request) -> Result> { let whole_body = hyper::body::aggregate(req).await?; let data: serde_json::Value = serde_json::from_reader(whole_body.reader())?; @@ -108,9 +160,26 @@ async fn decrypt(req: Request) -> Result> { } async fn encrypt(req: Request) -> Result> { + do_response!(inner_encrypt(req).await) +} + +async fn inner_encrypt(req: Request) -> XResult<(StatusCode, Value)> { let whole_body = hyper::body::aggregate(req).await?; - let data: serde_json::Value = serde_json::from_reader(whole_body.reader())?; - Ok(Response::builder().body(format!("{}", data).into())?) + let data: MultipleViewValue = serde_json::from_reader(whole_body.reader())?; + let value = data.to_bytes()?; + let mut key = opt_value_result!( get_master_key(), "Server is not init"); + let encrypt_result = jose::serialize_jwe_aes(&value, &key); + key.zeroize(); + + encrypt_result.map(|e| { + (StatusCode::OK, json!({ + "encrypted_value": e, + })) + }) +} + +async fn init(req: Request) -> Result> { + do_response!(inner_init(req).await) } #[derive(Serialize, Deserialize)] @@ -120,52 +189,65 @@ struct InitRequest { encrypted_master_key: Option, } -async fn init(req: Request) -> Result> { +async fn inner_init(req: Request) -> XResult<(StatusCode, Value)> { let whole_body = hyper::body::aggregate(req).await?; let init_request: InitRequest = serde_json::from_reader(whole_body.reader())?; let mut startup_rw_lock = STATUP_RW_LOCK.write().expect("Lock read startup rw lock error"); - let (status_code, body) = match &*startup_rw_lock { - None => (StatusCode::INTERNAL_SERVER_ERROR, json!({ "error": "internal_error", "error_message": "not init " })), + match &*startup_rw_lock { + None => return Ok((StatusCode::INTERNAL_SERVER_ERROR, json!({ "error": "internal_error", "error_message": "not init " }))), Some(memory_key) => match memory_key.master_key { - Some(_) => (StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "already init " })), - None => (StatusCode::OK, Value::Null), + Some(_) => return Ok((StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "already init " }))), + None => {} }, - }; - if status_code != StatusCode::OK { - return Ok(Response::builder().status(status_code).body(serde_json::to_string_pretty(&body)?.into())?); } - let (status_code, body) = if let Some(clear_master_key_base64) = init_request.clear_master_key_base64 { - let clear_master_key = base64::decode(clear_master_key_base64)?; - if clear_master_key.len() != 32 { - (StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "bad clear_master_key_hex length" })) - } else { - if let Some(k) = &mut *startup_rw_lock { - k.master_key = Some(clear_master_key); - } - (StatusCode::OK, json!({})) - } + let clear_master_key = if let Some(clear_master_key_base64) = &init_request.clear_master_key_base64 { + base64::decode(clear_master_key_base64)? } else if let Some(clear_master_key_hex) = init_request.clear_master_key_hex { - let clear_master_key = hex::decode(clear_master_key_hex)?; - if clear_master_key.len() != 32 { - (StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "bad clear_master_key_hex length" })) - } else { - if let Some(k) = &mut *startup_rw_lock { - k.master_key = Some(clear_master_key); - } - (StatusCode::OK, json!({})) - } + hex::decode(clear_master_key_hex)? } else if let Some(encrypted_master_key) = init_request.encrypted_master_key { - // TODO ... - (StatusCode::BAD_REQUEST, json!({ "error": "not_implement", "error_message": "not_implement" })) + if let Some(k) = &*startup_rw_lock { + let (clear_master_key, _) = jose::deserialize_jwe_rsa(&encrypted_master_key, &k.instance_rsa_key_pair.to_jwk_private_key())?; + clear_master_key + } else { + return Ok((StatusCode::INTERNAL_SERVER_ERROR, json!({ "error": "internal_error", "error_message": "not init " }))); + } } else { - (StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "master key is not provided" })) + return Ok((StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "master key is not assigned" }))); }; - Ok(Response::builder().status(status_code).body(serde_json::to_string_pretty(&body)?.into())?) + + if clear_master_key.len() != 32 { + return Ok((StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "bad clear_master_key length" }))); + } + + if let Some(k) = &mut *startup_rw_lock { + let conn = opt_result!(db::open_db(&k.database_file), "Open db failed: {}"); + let default_master_key_verification_key = db::find_key(&conn, db::DEFAULT_MASTER_KEY_VERIFICATION_KEY)?; + match default_master_key_verification_key { + None => { + let key = Key { + name: db::DEFAULT_MASTER_KEY_VERIFICATION_KEY.to_string(), + encrypted_key: jose::serialize_jwe_aes("LOCAL-MINI-KMS:MAGIC-VERIFICATION-KEY".as_bytes(), &clear_master_key)?, + }; + db::insert_key(&conn, &key)?; + } + Some(key) => { + debugging!("Found jwe: {}", &key.encrypted_key); + let _ = opt_result!(jose::deserialize_jwe_aes(&key.encrypted_key, &clear_master_key), "Deserialize master key verification key failed: {}"); + } + } + information!("Set master key success"); + k.master_key = Some(clear_master_key); + } + Ok((StatusCode::OK, json!({}))) } async fn status() -> Result> { + do_response!(inner_status().await) +} + +async fn inner_status() -> XResult<(StatusCode, Value)> { let startup_rw_lock = STATUP_RW_LOCK.read().expect("Lock read startup rw lock error"); let body = match &*startup_rw_lock { None => json!({ "status": "n/a" }), @@ -180,7 +262,7 @@ async fn status() -> Result> { }), } }; - Ok(Response::builder().body(serde_json::to_string_pretty(&body)?.into())?) + Ok((StatusCode::OK, body)) } async fn get_version() -> Result> { @@ -188,3 +270,11 @@ async fn get_version() -> Result> { "{} - {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION") ).into())?) } + +fn get_master_key() -> Option> { + let startup_rw_lock = STATUP_RW_LOCK.read().expect("Lock read startup rw lock error"); + match &*startup_rw_lock { + None => None, + Some(k) => k.master_key.clone(), + } +} -- 2.27.0 From 9c99f36eefd2187e756e9fef0d5c4acd123f9fe3 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 24 Jul 2022 18:03:36 +0800 Subject: [PATCH 07/10] gis --- src/jose.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/jose.rs b/src/jose.rs index 0688a1d..5ba8ae3 100644 --- a/src/jose.rs +++ b/src/jose.rs @@ -5,6 +5,9 @@ use josekit::jwe::JweHeader; use josekit::jwk::alg::rsa::RsaKeyPair; use josekit::jwk::Jwk; use rust_util::XResult; +use serde_json::Value; + +const LOCAL_KMS_PREFIX: &'static str = "LOCAL_KMS:"; pub fn generate_rsa_key(bits: u32) -> XResult { Ok(RsaKeyPair::generate(bits)?) @@ -13,23 +16,33 @@ pub fn generate_rsa_key(bits: u32) -> XResult { // pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult { // let mut header = JweHeader::new(); // header.set_content_encryption("A256GCM"); +// header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?; // let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?; -// Ok(jwe::serialize_compact(payload, &header, &encrypter)?) +// Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?)) // } pub fn deserialize_jwe_rsa(jwe: &str, jwk: &Jwk) -> XResult<(Vec, JweHeader)> { let decrypter = RsaesJweAlgorithm::RsaOaep.decrypter_from_jwk(jwk)?; - Ok(jwe::deserialize_json(jwe, &decrypter)?) + Ok(jwe::deserialize_json(&get_jwe(jwe), &decrypter)?) } pub fn serialize_jwe_aes(payload: &[u8], key: &[u8]) -> XResult { let mut header = JweHeader::new(); header.set_content_encryption("A256GCM"); + header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?; let encrypter = AeskwJweAlgorithm::A256kw.encrypter_from_bytes(key)?; - Ok(jwe::serialize_compact(payload, &header, &encrypter)?) + Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?)) } pub fn deserialize_jwe_aes(jwe: &str, key: &[u8]) -> XResult<(Vec, JweHeader)> { let decrypter = AeskwJweAlgorithm::A256kw.decrypter_from_bytes(key)?; - Ok(jwe::deserialize_compact(jwe, &decrypter)?) + Ok(jwe::deserialize_compact(&get_jwe(jwe), &decrypter)?) +} + +fn get_jwe(jwe: &str) -> String { + if jwe.starts_with(LOCAL_KMS_PREFIX) { + jwe.chars().skip(LOCAL_KMS_PREFIX.len()).collect() + } else { + jwe.to_string() + } } -- 2.27.0 From d0e1c503ca335d30b9c55eb641592921ba3b59f5 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 24 Jul 2022 18:04:50 +0800 Subject: [PATCH 08/10] feat: update local-mini-kms --- src/jose.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jose.rs b/src/jose.rs index 5ba8ae3..a6ca29c 100644 --- a/src/jose.rs +++ b/src/jose.rs @@ -7,7 +7,7 @@ use josekit::jwk::Jwk; use rust_util::XResult; use serde_json::Value; -const LOCAL_KMS_PREFIX: &'static str = "LOCAL_KMS:"; +const LOCAL_KMS_PREFIX: &'static str = "LKMS:"; pub fn generate_rsa_key(bits: u32) -> XResult { Ok(RsaKeyPair::generate(bits)?) -- 2.27.0 From 3c8e12a8d231bee55ad9cd02e53417f605244f33 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 24 Jul 2022 18:14:56 +0800 Subject: [PATCH 09/10] feat: add update --- src/serve.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/serve.rs b/src/serve.rs index 57b61af..852867a 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -71,6 +71,7 @@ async fn response_requests( ) -> Result> { match (req.method(), req.uri().path()) { (&Method::POST, "/init") => init(req).await, + (&Method::POST, "/update") => update().await, (&Method::POST, "/decrypt") => decrypt(req).await, (&Method::POST, "/encrypt") => encrypt(req).await, (&Method::GET, "/status") => status().await, @@ -122,6 +123,17 @@ fn init_instance(db: &str) -> XResult { } } +fn update_instance_rsa_key_pair() -> XResult { + let mut startup_rw_lock = STATUP_RW_LOCK.write().expect("Lock write startup rw lock error"); + match &mut *startup_rw_lock { + Some(k) => { + k.instance_rsa_key_pair = jose::generate_rsa_key(4096)?; + Ok(true) + } + None => Ok(false), + } +} + #[derive(Serialize, Deserialize)] struct MultipleViewValue { value: Option, @@ -178,6 +190,17 @@ async fn inner_encrypt(req: Request) -> XResult<(StatusCode, Value)> { }) } +async fn update() -> Result> { + do_response!(inner_update().await) +} + +async fn inner_update() -> XResult<(StatusCode, Value)> { + let update = update_instance_rsa_key_pair()?; + Ok((StatusCode::OK, json!({ + "update": update, + }))) +} + async fn init(req: Request) -> Result> { do_response!(inner_init(req).await) } -- 2.27.0 From b15da58154287e7668cc67f7676e4af42f6da8a0 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 24 Jul 2022 23:44:05 +0800 Subject: [PATCH 10/10] feat: v0.1.0 --- Cargo.lock | 66 +++++++++++++++++++ Cargo.toml | 1 + src/cli.rs | 181 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/jose.rs | 28 +++++--- src/serve.rs | 49 ++++++++++++-- 5 files changed, 307 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77a55c7..7c24477 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,6 +72,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + [[package]] name = "bytes" version = "1.1.0" @@ -105,6 +114,15 @@ dependencies = [ "vec_map", ] +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -114,6 +132,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -217,6 +255,16 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.7" @@ -409,6 +457,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "sha2", "tokio", "zeroize", ] @@ -696,6 +745,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -884,6 +944,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + [[package]] name = "unicode-ident" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index b03e4f9..ccb12ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ zeroize = "1.5.7" clap = "2.33" hex = "0.4" base64 = "0.13.0" +sha2 = "0.10.2" lazy_static = "1.4.0" serde_derive = "1.0" serde = { version = "1.0", features = ["derive"] } diff --git a/src/cli.rs b/src/cli.rs index fb60d75..ae567c1 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,14 @@ +use std::io::Write; + use clap::{App, Arg, ArgMatches, SubCommand}; -use rust_util::simple_error; +use hyper::{Body, Client, Method, Request, Response, StatusCode}; +use hyper::body::Buf; +use josekit::jwk::Jwk; +use rust_util::{debugging, opt_value_result, simple_error, success, XResult}; use rust_util::util_clap::{Command, CommandError}; +use serde_json::{json, Value}; + +use crate::jose; pub struct CommandImpl; @@ -9,10 +17,175 @@ impl Command for CommandImpl { fn subcommand<'a>(&self) -> App<'a, 'a> { SubCommand::with_name(self.name()).about("Local mini KMS cli") - .arg(Arg::with_name("connect").long("connect").takes_value(true).default_value("127.0.0.1:6567").help("Connect server")) + .arg(Arg::with_name("connect").long("connect").takes_value(true).default_value("127.0.0.1:5567").help("Connect server")) + .arg(Arg::with_name("init").long("init").help("Init server")) + .arg(Arg::with_name("offline-init").long("offline-init").help("Offline init server")) + .arg(Arg::with_name("encrypt").long("encrypt").help("Encrypt text")) + .arg(Arg::with_name("decrypt").long("decrypt").help("Decrypt text")) + .arg(Arg::with_name("value").long("value").takes_value(true).help("Value, for encrypt or decrypt")) + .arg(Arg::with_name("value-hex").long("value-hex").takes_value(true).help("Value(hex), for encrypt")) + .arg(Arg::with_name("value-base64").long("value-base64").takes_value(true).help("Value(base64), for encrypt")) } - fn run(&self, _arg_matches: &ArgMatches, _sub_arg_matches: &ArgMatches) -> CommandError { - simple_error!("Not implemented") + fn run(&self, arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { + let init = sub_arg_matches.is_present("init"); + let offline_init = sub_arg_matches.is_present("offline-init"); + let encrypt = sub_arg_matches.is_present("encrypt"); + let decrypt = sub_arg_matches.is_present("decrypt"); + let rt = tokio::runtime::Runtime::new().expect("Create tokio runtime error"); + if init { + rt.block_on(async { + do_init(arg_matches, sub_arg_matches).await + }) + } else if offline_init { + do_offline_init(arg_matches, sub_arg_matches) + } else if encrypt { + rt.block_on(async { + do_encrypt(arg_matches, sub_arg_matches).await + }) + } else if decrypt { + rt.block_on(async { + do_decrypt(arg_matches, sub_arg_matches).await + }) + } else { + simple_error!("Need a flag") + } } +} + +async fn do_init(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_>) -> CommandError { + let connect = sub_arg_matches.value_of("connect").expect("Get argument listen error"); + + let client = Client::new(); + let uri = format!("http://{}/status", connect); + debugging!("Request uri: {}", &uri); + let req = Request::builder().method(Method::GET).uri(uri).body(Body::empty())?; + let req_response = client.request(req).await?; + if req_response.status() != StatusCode::OK { + return simple_error!("Server status is not success: {}", req_response.status().as_u16()); + } + let data = response_to_value(req_response).await?; + debugging!("Get status: {}", &data); + let status = &data["status"]; + if let Some(status) = status.as_str() { + if status == "ready" { + success!("Server is already init"); + return Ok(Some(0)); + } + if status != "not-ready" { + return simple_error!("Server status is NOT not-ready"); + } + } + let instance_public_key_jwk = &data["instance_public_key_jwk"]; + println!("Instance server public key JWK: {}", instance_public_key_jwk); + + let line = read_line("Input encrypted master key: ")?; + let uri = format!("http://{}/init", connect); + debugging!("Request uri: {}", &uri); + let body = json!({ + "encrypted_master_key": line, + }); + let body = serde_json::to_string(&body)?; + let req = Request::builder().method(Method::POST).uri(uri).body(Body::from(body))?; + + let req_response = client.request(req).await?; + if req_response.status() != StatusCode::OK { + let status = req_response.status().as_u16(); + let data = response_to_value(req_response).await?; + return simple_error!("Server status is not success: {}, response: {}", status, data); + } + success!("Init finished"); + Ok(Some(0)) +} + +async fn do_encrypt(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_>) -> CommandError { + let connect = sub_arg_matches.value_of("connect").expect("Get argument listen error"); + let value = sub_arg_matches.value_of("value"); + let value_hex = sub_arg_matches.value_of("value-hex"); + let value_base64 = sub_arg_matches.value_of("value-base64"); + + let client = Client::new(); + let uri = format!("http://{}/encrypt", connect); + debugging!("Request uri: {}", &uri); + let body = if let Some(value) = value { + json!({ "value": value }) + } else if let Some(value_hex) = value_hex { + json!({ "value_hex": value_hex }) + } else if let Some(value_base64) = value_base64 { + json!({ "value_base64": value_base64 }) + } else { + return simple_error!("Require one of value, value-hex, value-base64"); + }; + let body = serde_json::to_string(&body)?; + let req = Request::builder().method(Method::POST).uri(uri).body(Body::from(body))?; + + let req_response = client.request(req).await?; + if req_response.status() != StatusCode::OK { + let status = req_response.status().as_u16(); + let data = response_to_value(req_response).await?; + return simple_error!("Server status is not success: {}, response: {}", status, data); + } + let data = response_to_value(req_response).await?; + success!("Encrypted value: {}", data["encrypted_value"].as_str().expect("Get encrypted_value error")); + Ok(Some(0)) +} + +async fn do_decrypt(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_>) -> CommandError { + let connect = sub_arg_matches.value_of("connect").expect("Get argument listen error"); + let value = opt_value_result!(sub_arg_matches.value_of("value"), "Argument value required"); + + let client = Client::new(); + let uri = format!("http://{}/decrypt", connect); + debugging!("Request uri: {}", &uri); + let body = json!({ "encrypted_value": value }); + let body = serde_json::to_string(&body)?; + let req = Request::builder().method(Method::POST).uri(uri).body(Body::from(body))?; + + let req_response = client.request(req).await?; + if req_response.status() != StatusCode::OK { + let status = req_response.status().as_u16(); + let data = response_to_value(req_response).await?; + return simple_error!("Server status is not success: {}, response: {}", status, data); + } + let data = response_to_value(req_response).await?; + success!("Encrypted value(hex): {}", data["value_hex"].as_str().expect("Get value_hex error")); + success!("Encrypted value(base64): {}", data["value_base64"].as_str().expect("Get value_base64 error")); + success!("Encrypted value: {}", String::from_utf8_lossy(&hex::decode(data["value_hex"].as_str().expect("Get value_hex error"))?).to_string()); + Ok(Some(0)) +} + +fn do_offline_init(_arg_matches: &ArgMatches<'_>, _sub_arg_matches: &ArgMatches<'_>) -> CommandError { + let line = read_line("Input master key: ")?; + let master_key = if line.starts_with("hex:") { + let hex: String = line.chars().skip(4).collect(); + hex::decode(&hex)? + } else if line.starts_with("base64:") { + let base64: String = line.chars().skip(7).collect(); + base64::decode(&base64)? + } else { + line.as_bytes().to_vec() + }; + let jwk = read_line("Input JWK: ")?; + let jwk = Jwk::from_bytes(jwk.as_bytes())?; + let encrypted_master_key = jose::serialize_jwe_rsa(&master_key, &jwk)?; + + success!("Encrypted master key: {}", encrypted_master_key); + Ok(Some(0)) +} + +fn read_line(prompt: &str) -> XResult { + std::io::stdout().write(prompt.as_bytes()).ok(); + std::io::stdout().flush().ok(); + let mut line = String::new(); + if let Err(e) = std::io::stdin().read_line(&mut line) { + return simple_error!("Read from terminal failed: {}", e); + } + Ok(line.trim().to_string()) +} + +async fn response_to_value(response: Response) -> XResult { + let req_body = response.into_body(); + let whole_body = hyper::body::aggregate(req_body).await?; + let data: Value = serde_json::from_reader(whole_body.reader())?; + Ok(data) } \ No newline at end of file diff --git a/src/jose.rs b/src/jose.rs index a6ca29c..ae42240 100644 --- a/src/jose.rs +++ b/src/jose.rs @@ -6,6 +6,7 @@ use josekit::jwk::alg::rsa::RsaKeyPair; use josekit::jwk::Jwk; use rust_util::XResult; use serde_json::Value; +use sha2::Digest; const LOCAL_KMS_PREFIX: &'static str = "LKMS:"; @@ -13,23 +14,24 @@ pub fn generate_rsa_key(bits: u32) -> XResult { Ok(RsaKeyPair::generate(bits)?) } -// pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult { -// let mut header = JweHeader::new(); -// header.set_content_encryption("A256GCM"); -// header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?; -// let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?; -// Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?)) -// } +pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult { + let mut header = JweHeader::new(); + header.set_content_encryption("A256GCM"); + header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?; + let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?; + Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?)) +} pub fn deserialize_jwe_rsa(jwe: &str, jwk: &Jwk) -> XResult<(Vec, JweHeader)> { let decrypter = RsaesJweAlgorithm::RsaOaep.decrypter_from_jwk(jwk)?; - Ok(jwe::deserialize_json(&get_jwe(jwe), &decrypter)?) + Ok(jwe::deserialize_compact(&get_jwe(jwe), &decrypter)?) } pub fn serialize_jwe_aes(payload: &[u8], key: &[u8]) -> XResult { let mut header = JweHeader::new(); header.set_content_encryption("A256GCM"); header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?; + header.set_claim("version", Some(Value::String(get_master_key_checksum(key))))?; let encrypter = AeskwJweAlgorithm::A256kw.encrypter_from_bytes(key)?; Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?)) } @@ -39,6 +41,16 @@ pub fn deserialize_jwe_aes(jwe: &str, key: &[u8]) -> XResult<(Vec, JweHeader Ok(jwe::deserialize_compact(&get_jwe(jwe), &decrypter)?) } +fn get_master_key_checksum(key: &[u8]) -> String { + let digest = sha2::Sha256::digest(&key); + let digest = sha2::Sha256::digest(&digest.as_slice()); + let digest = sha2::Sha256::digest(&digest.as_slice()); + let digest = sha2::Sha256::digest(&digest.as_slice()); + let digest = sha2::Sha256::digest(&digest.as_slice()); + let digest = sha2::Sha256::digest(&digest.as_slice()); + hex::encode(&digest[0..8]) +} + fn get_jwe(jwe: &str) -> String { if jwe.starts_with(LOCAL_KMS_PREFIX) { jwe.chars().skip(LOCAL_KMS_PREFIX.len()).collect() diff --git a/src/serve.rs b/src/serve.rs index 852867a..f90661d 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -7,10 +7,10 @@ use hyper::client::HttpConnector; use hyper::service::{make_service_fn, service_fn}; use josekit::jwk::alg::rsa::RsaKeyPair; use josekit::jwk::KeyPair; -use rust_util::{debugging, failure_and_exit, information, opt_result, opt_value_result, simple_error, success, XResult}; +use rust_util::{debugging, failure_and_exit, information, opt_result, simple_error, success, XResult}; use rust_util::util_clap::{Command, CommandError}; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; +use serde_json::{json, Map, Value}; use zeroize::Zeroize; use crate::{db, jose}; @@ -165,10 +165,42 @@ impl MultipleViewValue { } } + +#[derive(Serialize, Deserialize)] +struct DecryptRequest { + encrypted_value: String, +} + async fn decrypt(req: Request) -> Result> { + do_response!(inner_decrypt(req).await) +} + +async fn inner_decrypt(req: Request) -> XResult<(StatusCode, Value)> { let whole_body = hyper::body::aggregate(req).await?; - let data: serde_json::Value = serde_json::from_reader(whole_body.reader())?; - Ok(Response::builder().body(format!("{}", data).into())?) + let data: DecryptRequest = serde_json::from_reader(whole_body.reader())?; + + debugging!("To be decrypted value: {}", &data.encrypted_value); + let mut key = match get_master_key() { + None => return Ok((StatusCode::BAD_REQUEST, json!({ "error": "status_not_ready" }))), + Some(key) => key, + }; + let decrypted_value = jose::deserialize_jwe_aes(&data.encrypted_value, &key); + key.zeroize(); + + decrypted_value.map(|v| { + let v = MultipleViewValue::from(&v.0); + let mut map = Map::new(); + if let Some(v) = &v.value { + map.insert("value".to_string(), Value::String(v.to_string())); + } + if let Some(v) = &v.value_hex { + map.insert("value_hex".to_string(), Value::String(v.to_string())); + } + if let Some(v) = &v.value_base64 { + map.insert("value_base64".to_string(), Value::String(v.to_string())); + } + (StatusCode::OK, Value::Object(map)) + }) } async fn encrypt(req: Request) -> Result> { @@ -179,7 +211,10 @@ async fn inner_encrypt(req: Request) -> XResult<(StatusCode, Value)> { let whole_body = hyper::body::aggregate(req).await?; let data: MultipleViewValue = serde_json::from_reader(whole_body.reader())?; let value = data.to_bytes()?; - let mut key = opt_value_result!( get_master_key(), "Server is not init"); + let mut key = match get_master_key() { + None => return Ok((StatusCode::BAD_REQUEST, json!({ "error": "status_not_ready" }))), + Some(key) => key, + }; let encrypt_result = jose::serialize_jwe_aes(&value, &key); key.zeroize(); @@ -230,6 +265,7 @@ async fn inner_init(req: Request) -> XResult<(StatusCode, Value)> { } else if let Some(clear_master_key_hex) = init_request.clear_master_key_hex { hex::decode(clear_master_key_hex)? } else if let Some(encrypted_master_key) = init_request.encrypted_master_key { + debugging!("Received encrypted master key: {}", encrypted_master_key); if let Some(k) = &*startup_rw_lock { let (clear_master_key, _) = jose::deserialize_jwe_rsa(&encrypted_master_key, &k.instance_rsa_key_pair.to_jwk_private_key())?; clear_master_key @@ -262,6 +298,7 @@ async fn inner_init(req: Request) -> XResult<(StatusCode, Value)> { } information!("Set master key success"); k.master_key = Some(clear_master_key); + k.instance_rsa_key_pair = jose::generate_rsa_key(4096)?; } Ok((StatusCode::OK, json!({}))) } @@ -278,10 +315,10 @@ async fn inner_status() -> XResult<(StatusCode, Value)> { None => json!({ "status": "not-ready", "instance_public_key_jwk": memory_key.instance_rsa_key_pair.to_jwk_key_pair().to_public_key()?, + "instance_public_key_pem": String::from_utf8_lossy(&memory_key.instance_rsa_key_pair.to_pem_public_key()).to_string(), }), Some(_) => json!({ "status": "ready", - "instance_public_key_jwk": memory_key.instance_rsa_key_pair.to_jwk_key_pair().to_public_key()?, }), } }; -- 2.27.0