diff --git a/Cargo.lock b/Cargo.lock index 1defd8b..6c793af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,27 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -12,16 +33,65 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.66" +name = "anstream" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "async-trait" -version = "0.1.59" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", @@ -36,13 +106,13 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.1" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08b108ad2665fa3f6e6a517c3d80ec3e77d224c47d605167aefaa5d7ef97fa48" +checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" dependencies = [ "async-trait", "axum-core", - "bitflags", + "bitflags 1.3.2", "bytes", "futures-util", "http", @@ -62,16 +132,15 @@ dependencies = [ "sync_wrapper", "tokio", "tower", - "tower-http", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.3.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b8558f5a0581152dc94dcd289132a1d377494bdeafcd41869b3258e3e2ad92" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", "bytes", @@ -86,9 +155,9 @@ dependencies = [ [[package]] name = "axum-extra" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256d21542ab2ccf04a433fdb025a466ca5c28ec6c63ee69d1e71b41b475efbac" +checksum = "f9a320103719de37b7b4da4c8eb629d4573f6bcfd3dfe80d3208806895ccf81d" dependencies = [ "axum", "axum-macros", @@ -108,9 +177,9 @@ dependencies = [ [[package]] name = "axum-macros" -version = "0.3.0" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4df0fc33ada14a338b799002f7e8657711422b25d4e16afb032708d6b185621" +checksum = "2bb524613be645939e280b7279f7b017f98cf7f5ef084ec374df373530e73277" dependencies = [ "heck", "proc-macro2", @@ -119,22 +188,37 @@ dependencies = [ ] [[package]] -name = "base16ct" -version = "0.1.1" +name = "backtrace" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -143,28 +227,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "block-buffer" -version = "0.9.0" +name = "bitflags" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "byteorder" @@ -174,15 +255,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.77" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -192,13 +273,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "time", "wasm-bindgen", @@ -206,28 +287,45 @@ dependencies = [ ] [[package]] -name = "clap" -version = "4.0.29" +name = "cipher" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "bitflags", + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" +dependencies = [ + "clap_builder", "clap_derive", - "clap_lex", - "is-terminal", "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.0.21" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", "syn", @@ -235,28 +333,21 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "colorchoice" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc" [[package]] name = "core-foundation" @@ -270,27 +361,27 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "crypto-bigint" -version = "0.4.9" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -307,55 +398,25 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.0" +version = "4.0.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +checksum = "436ace70fc06e06f7f689d2624dc4e2f0ea666efb5aa704215f7249ae6e047a7" dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", "subtle", - "zeroize", ] [[package]] -name = "cxx" -version = "1.0.83" +name = "curve25519-dalek-derive" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", @@ -364,31 +425,21 @@ dependencies = [ [[package]] name = "der" -version = "0.6.0" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" dependencies = [ "const-oid", - "pem-rfc7468", "zeroize", ] [[package]] name = "digest" -version = "0.9.0" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer 0.10.3", + "block-buffer", "const-oid", "crypto-common", "subtle", @@ -396,53 +447,52 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ "der", + "digest", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] name = "ed25519" -version = "1.5.2" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" dependencies = [ "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.0.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "faa8e9049d5d72bfc12acbc05914731b5322f79b5e2f195e9f2d705fca22ab4c" dependencies = [ "curve25519-dalek", "ed25519", - "rand 0.7.3", - "serde", - "sha2 0.9.9", - "zeroize", + "sha2", ] [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest", "ff", "generic-array", "group", - "rand_core 0.6.4", + "pkcs8", + "rand_core", "sec1", "subtle", "zeroize", @@ -450,22 +500,22 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if", ] [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys", ] [[package]] @@ -480,23 +530,29 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core 0.6.4", + "rand_core", "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" + [[package]] name = "fnv" version = "1.0.7" @@ -520,45 +576,45 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-task", @@ -568,30 +624,20 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.1.16" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -599,21 +645,27 @@ dependencies = [ ] [[package]] -name = "group" -version = "0.12.1" +name = "gimli" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core", "subtle", ] [[package]] name = "h2" -version = "0.3.15" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -642,17 +694,23 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" dependencies = [ - "libc", + "serde", ] [[package]] @@ -661,14 +719,14 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest", ] [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -706,9 +764,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.23" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -743,33 +801,32 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] name = "idna" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -777,14 +834,23 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.12" @@ -796,43 +862,43 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.3" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ + "hermit-abi", "libc", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] name = "ipnet" -version = "2.5.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.1" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "io-lifetimes", - "rustix", - "windows-sys 0.42.0", + "rustix 0.38.3", + "windows-sys", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -847,11 +913,11 @@ dependencies = [ "base64ct", "chrono", "hmac", - "rand_core 0.6.4", + "rand_core", "serde", "serde_cbor", "serde_json", - "sha2 0.10.6", + "sha2", "smallvec", "subtle", "zeroize", @@ -868,39 +934,33 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.137" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libm" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" - -[[package]] -name = "link-cplusplus" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" -dependencies = [ - "cc", -] +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "linux-raw-sys" -version = "0.1.3" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "matchit" @@ -916,20 +976,28 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] [[package]] name = "mio" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -962,9 +1030,9 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" dependencies = [ "byteorder", "lazy_static", @@ -972,8 +1040,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.5", - "serde", + "rand", "smallvec", "zeroize", ] @@ -1010,24 +1077,27 @@ dependencies = [ ] [[package]] -name = "once_cell" -version = "1.16.0" +name = "object" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] [[package]] -name = "opaque-debug" -version = "0.3.0" +name = "once_cell" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.43" +version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020433887e44c27ff16365eaa2d380547a94544ad509aff6eb5b6e3e0b27b376" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1038,9 +1108,9 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", @@ -1055,23 +1125,16 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.78" +version = "0.9.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d5c8cb6e57b3a3612064d7b18b117912b4ce70955c2504d4b741c9e244b132" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", "vcpkg", ] -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - [[package]] name = "overload" version = "0.1.1" @@ -1080,55 +1143,57 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "p256" -version = "0.11.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "primeorder", + "sha2", ] [[package]] name = "p384" -version = "0.11.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "primeorder", + "sha2", ] [[package]] name = "pem-rfc7468" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ "base64ct", ] [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", @@ -1137,9 +1202,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -1149,21 +1214,20 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs1" -version = "0.4.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ "der", "pkcs8", "spki", - "zeroize", ] [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1171,9 +1235,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "platforms" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" [[package]] name = "ppv-lite86" @@ -1182,60 +1252,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "primeorder" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", + "elliptic-curve", ] [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -1243,18 +1285,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -1264,16 +1296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -1282,41 +1305,23 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.8", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", + "bitflags 1.3.2", ] [[package]] name = "reqwest" -version = "0.11.13" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64", "bytes", @@ -1351,83 +1356,105 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rsa" -version = "0.7.2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ "byteorder", - "digest 0.10.6", + "const-oid", + "digest", "num-bigint-dig", "num-integer", "num-iter", "num-traits", "pkcs1", "pkcs8", - "rand_core 0.6.4", + "rand_core", + "sha2", "signature", - "smallvec", + "spki", "subtle", "zeroize", ] [[package]] -name = "rustix" -version = "0.36.4" +name = "rustc-demangle" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb93e85278e08bb5788653183213d3a60fc242b10cb9be96586f5a73dcb67c23" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "bitflags", + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +dependencies = [ + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys 0.42.0", + "linux-raw-sys 0.3.8", + "windows-sys", +] + +[[package]] +name = "rustix" +version = "0.38.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", + "windows-sys", ] [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys", ] -[[package]] -name = "scratch" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" - [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" dependencies = [ "base16ct", "der", @@ -1439,11 +1466,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -1452,19 +1479,25 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", ] [[package]] -name = "serde" -version = "1.0.148" +name = "semver" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + +[[package]] +name = "serde" +version = "1.0.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd51c3db8f9500d531e6c12dd0fd4ad13d133e9117f5aebac3cdbb8b6d9824b0" dependencies = [ "serde_derive", ] @@ -1481,9 +1514,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.148" +version = "1.0.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" +checksum = "27738cfea0d944ab72c3ed01f3d5f23ec4322af8a1431e40ce630e4c01ea74fd" dependencies = [ "proc-macro2", "quote", @@ -1492,9 +1525,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa", "ryu", @@ -1503,10 +1536,11 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.8" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "184c643044780f7ceb59104cef98a5a6f12cb2288a7bc701ab93a362b49fd47d" +checksum = "8acc4422959dd87a76cb117c191dcbffc20467f06c9100b76721dab370f24d3a" dependencies = [ + "itoa", "serde", ] @@ -1524,26 +1558,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.9" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest", ] [[package]] @@ -1556,35 +1577,41 @@ dependencies = [ ] [[package]] -name = "signature" -version = "1.6.4" +name = "shell-escape" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", - "rand_core 0.6.4", + "digest", + "rand_core", ] [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -1598,16 +1625,56 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", ] [[package]] -name = "ssh-cert-dist" +name = "ssh-cert-dist-client" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "axum-extra", + "chrono", + "clap", + "rand", + "reqwest", + "serde", + "ssh-cert-dist-common", + "ssh-key", + "tempfile", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", + "url", +] + +[[package]] +name = "ssh-cert-dist-common" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "axum", + "axum-extra", + "hex", + "serde", + "ssh-key", + "tempfile", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "ssh-cert-dist-server" version = "0.1.0" dependencies = [ "anyhow", @@ -1617,9 +1684,10 @@ dependencies = [ "chrono", "clap", "jwt-compact", - "rand 0.8.5", - "reqwest", + "rand", "serde", + "shell-escape", + "ssh-cert-dist-common", "ssh-key", "tempfile", "thiserror", @@ -1628,35 +1696,48 @@ dependencies = [ "tower-http", "tracing", "tracing-subscriber", - "url", +] + +[[package]] +name = "ssh-cipher" +version = "0.1.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c654ae3f0ee989c7ff306b33f644c776af891d30a082ba3e22f47c23a40b5d1a" +dependencies = [ + "cipher", + "ssh-encoding", ] [[package]] name = "ssh-encoding" -version = "0.1.0" -source = "git+https://github.com/a-dma/SSH.git?branch=u2f_signatures#ce0c34c935acd2caf7174d33039ec1c4557119de" +version = "0.2.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde709d55a07116c56152154338b23501571f14c5ab58f9d3d6acfe38ab6c4df" dependencies = [ "base64ct", "pem-rfc7468", - "sha2 0.10.6", + "sha2", ] [[package]] name = "ssh-key" -version = "0.5.1" -source = "git+https://github.com/a-dma/SSH.git?branch=u2f_signatures#ce0c34c935acd2caf7174d33039ec1c4557119de" +version = "0.6.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "110fff26e39d649d1764dbaf7dd7c38da89752219c6c53ed09809dc42fd431a2" dependencies = [ "ed25519-dalek", "num-bigint-dig", "p256", "p384", - "rand_core 0.6.4", + "rand_core", "rsa", "sec1", "serde", - "sha2 0.10.6", + "sha2", "signature", + "ssh-cipher", "ssh-encoding", + "subtle", "zeroize", ] @@ -1668,15 +1749,15 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "1.0.104" +version = "2.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" +checksum = "36ccaf716a23c35ff908f91c971a86a9a71af5998c1d8f10e828d9f55f68ac00" dependencies = [ "proc-macro2", "quote", @@ -1685,59 +1766,38 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "tempfile" -version = "3.3.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", + "rustix 0.37.23", + "windows-sys", ] [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", @@ -1746,10 +1806,11 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if", "once_cell", ] @@ -1775,33 +1836,33 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.22.0" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", "pin-project-lite", "socket2", "tokio-macros", "tracing", - "winapi", + "windows-sys", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", @@ -1810,9 +1871,9 @@ dependencies = [ [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -1820,9 +1881,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -1850,11 +1911,11 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytes", "futures-core", "futures-util", @@ -1895,9 +1956,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", @@ -1906,9 +1967,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -1927,9 +1988,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -1941,27 +2002,27 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-normalization" @@ -1972,29 +2033,23 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "valuable" version = "0.1.0" @@ -2015,20 +2070,13 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -2043,9 +2091,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2053,9 +2101,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", @@ -2068,9 +2116,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.33" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -2080,9 +2128,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2090,9 +2138,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -2103,15 +2151,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -2133,15 +2181,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2149,104 +2188,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winreg" @@ -2259,21 +2273,20 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", "syn", - "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index 014bc21..67dca87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,43 +1,8 @@ -[package] -name = "ssh-cert-dist" -version = "0.1.0" -authors = ["shimun "] -edition = "2021" +[workspace] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[features] -default = [ "client", "reload", "info", "authorized" ] -reload = [] -authorized =[ "dep:jwt-compact" ] -index = [] -info = [ "axum/json", "ssh-key/serde" ] -client = [ "dep:url", "dep:reqwest" ] - - -[dependencies] -anyhow = "1.0.66" -async-trait = "0.1.59" -axum = { version = "0.6.1", features = ["http2"] } -axum-extra = { version = "0.4.1", features = ["typed-routing"] } -chrono = "0.4.23" -clap = { version = "4.0.29", features = ["env", "derive"] } -jwt-compact = { version = "0.6.0", features = ["serde_cbor", "std", "clock"], optional = true } -rand = "0.8.5" -reqwest = { version = "0.11.13", optional = true } -serde = { version = "1.0.148", features = ["derive"] } -ssh-key = { version = "0.5.1", features = ["ed25519", "p256", "p384", "rsa", "signature"] } -thiserror = "1.0.37" -tokio = { version = "1.22.0", features = ["io-std", "test-util", "tracing", "macros", "fs"] } -tower = { version = "0.4.13", features = ["util"] } -tower-http = { version = "0.3.4", features = ["map-request-body", "trace"] } -tracing = { version = "0.1.37", features = ["release_max_level_debug"] } -tracing-subscriber = "0.3.16" -url = { version = "2.3.1", optional = true } - -[patch.crates-io] -ssh-key = { git = "https://github.com/a-dma/SSH.git", branch = "u2f_signatures" } - -[dev-dependencies] -tempfile = "3.3.0" +members = [ + "common", + "server", + "client", +] diff --git a/client/Cargo.toml b/client/Cargo.toml new file mode 100644 index 0000000..ef0a453 --- /dev/null +++ b/client/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "ssh-cert-dist-client" +version = "0.1.0" +authors = ["shimun "] +edition = "2021" + +[[bin]] +name = "sshcd" +path = "src/main.rs" + +[dependencies] +anyhow = "1.0.66" +async-trait = "0.1.59" +axum-extra = { version = "0.4.1", features = ["typed-routing"] } +chrono = "0.4.23" +clap = { version = "4.0.29", features = ["env", "derive"] } +rand = "0.8.5" +reqwest = { version = "0.11.13" } +serde = { version = "1.0.148", features = ["derive"] } +ssh-key = { version = "0.6.0-pre.0", features = ["ed25519", "p256", "p384", "rsa", "serde"] } +thiserror = "1.0.37" +tokio = { version = "1.22.0", features = ["io-std", "test-util", "tracing", "macros", "fs"] } +tracing = { version = "0.1.37", features = ["release_max_level_debug"] } +tracing-subscriber = "0.3.16" +url = { version = "2.3.1" } +ssh-cert-dist-common = { path = "../common" } + +[dev-dependencies] +tempfile = "3.3.0" + +[profile.relese] +opt-level = 1 diff --git a/src/client.rs b/client/src/client.rs similarity index 85% rename from src/client.rs rename to client/src/client.rs index 16b9ff3..00c2a3c 100644 --- a/src/client.rs +++ b/client/src/client.rs @@ -1,20 +1,17 @@ use anyhow::bail; use axum_extra::routing::TypedPath; -use clap::{Args, Parser, Subcommand}; +use clap::{Parser, Subcommand}; use reqwest::{Client, StatusCode}; use ssh_key::Certificate; -use std::io::{stdin, stdout}; use std::path::PathBuf; use std::time::{Duration, SystemTime}; use tokio::fs; +use tokio::io::{stdin, AsyncBufReadExt, BufReader}; use tracing::{debug, error, info, instrument, trace}; use url::Url; -use crate::api::PutCert; -use crate::certs::load_cert; -use crate::env_key; -use crate::{api::GetCert, certs::read_dir}; +use ssh_cert_dist_common::*; #[derive(Parser)] pub struct ClientArgs { @@ -30,7 +27,9 @@ pub struct ClientArgs { pub struct FetchArgs { #[clap(flatten)] args: ClientArgs, - #[clap(short = 'c', long = "cert-dir", env = env_key!("CERT_DIR") )] + #[clap(short = 'k', long = "key-update", env = env_key!("KEY_UPDATE"))] + prohibit_key_update: bool, + #[clap(short = 'c', long = "cert-dir", env = env_key!("CERT_DIR"))] cert_dir: PathBuf, /// minimum time in days between now and expiry to consider checking #[clap(short = 'd', long = "days", default_value = "60", env = env_key!("MIN_DELTA_DAYS"))] @@ -46,7 +45,7 @@ pub struct UploadArgs { files: Vec, } -#[derive(Args)] +#[derive(Parser)] pub struct ClientCommand { #[clap(subcommand)] cmd: ClientCommands, @@ -112,15 +111,18 @@ async fn upload_cert(client: Client, url: Url, cert: Certificate) -> anyhow::Res async fn fetch( FetchArgs { cert_dir, + prohibit_key_update, min_delta_days: min_delta, args: ClientArgs { api, interactive }, }: FetchArgs, ) -> anyhow::Result<()> { - let certs = read_dir(&cert_dir).await?; + let certs = read_certs_dir(&cert_dir).await?; + // let publics_keys = read_pubkey_dir(&cert_dir).await?; let client = reqwest::Client::new(); let threshold_exp = min_delta.and_then(|min_delta| { SystemTime::now().checked_add(Duration::from_secs(60 * 60 * 24 * min_delta as u64)) }); + // let standalone_certs = publics_keys.into_iter().map(|(name, key)| ) let updates = certs .into_iter() .filter(|cert| { @@ -137,8 +139,13 @@ async fn fetch( let client = client.clone(); tokio::spawn(async move { fetch_cert(client, url, cert).await }) }); + let mut stdin = BufReader::new(stdin()).lines(); for cert in updates { if let Ok(Some((cert, update))) = cert.await? { + if prohibit_key_update && cert.public_key() != update.public_key() { + debug!(?update, "skipping cert due to key change"); + continue; + } if interactive { println!("certificate update: {}", cert.key_id()); println!( @@ -147,9 +154,8 @@ async fn fetch( update.valid_before() ); println!("update? : (y/n)"); - let mut yes = String::with_capacity(3); - stdin().read_line(&mut yes)?; - if !yes.starts_with(['y', 'Y']) { + let yes = stdin.next_line().await?; + if !matches!(yes, Some(line) if line.starts_with(['y', 'Y'])) { break; } } diff --git a/client/src/main.rs b/client/src/main.rs new file mode 100644 index 0000000..e187af3 --- /dev/null +++ b/client/src/main.rs @@ -0,0 +1,10 @@ +use clap::Parser; + +mod client; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> anyhow::Result<()> { + tracing_subscriber::fmt::init(); + + client::run(client::ClientCommand::parse()).await +} diff --git a/common/Cargo.toml b/common/Cargo.toml new file mode 100644 index 0000000..548a0c6 --- /dev/null +++ b/common/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "ssh-cert-dist-common" +version = "0.1.0" +authors = ["shimun "] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.66" +async-trait = "0.1.59" +axum = { version = "0.6.1" } +axum-extra = { version = "0.4.1", features = ["typed-routing"] } +hex = { version = "0.4.3", features = ["serde"] } +serde = { version = "1.0.148", features = ["derive"] } +ssh-key = { version = "0.6.0-pre.0", features = ["ed25519", "p256", "p384", "rsa"] } +thiserror = "1.0.37" +tokio = { version = "1.22.0", features = ["io-std", "test-util", "tracing", "macros", "fs"] } +tracing = { version = "0.1.37", features = ["release_max_level_debug"] } +tracing-subscriber = "0.3.16" + +[dev-dependencies] +tempfile = "3.3.0" + diff --git a/src/certs.rs b/common/src/certs.rs similarity index 70% rename from src/certs.rs rename to common/src/certs.rs index 67cff7b..b0a4575 100644 --- a/src/certs.rs +++ b/common/src/certs.rs @@ -24,11 +24,11 @@ pub async fn read_certs( if !ca_dir.exists() { return Ok(Vec::new()); } - read_dir(&ca_dir).await + read_certs_dir(&ca_dir).await } #[instrument] -pub async fn read_dir(path: impl AsRef + Debug) -> anyhow::Result> { +pub async fn read_certs_dir(path: impl AsRef + Debug) -> anyhow::Result> { let mut dir = fs::read_dir(path.as_ref()) .await .with_context(|| format!("read certs dir '{:?}'", path.as_ref()))?; @@ -55,6 +55,26 @@ pub async fn read_dir(path: impl AsRef + Debug) -> anyhow::Result + Debug) -> anyhow::Result> { + let mut dir = fs::read_dir(path.as_ref()) + .await + .with_context(|| format!("read certs dir '{:?}'", path.as_ref()))?; + let mut pubs = Vec::new(); + while let Some(entry) = dir.next_entry().await? { + //TODO: investigate why path().ends_with doesn't work + let file_name = entry.file_name().into_string().unwrap(); + if !file_name.ends_with(".pub") || file_name.ends_with("-cert.pub") { + trace!("skipped {:?} due to missing '.pub' extension", entry.path()); + continue; + } + let cert = load_public_key(entry.path()).await?; + if let Some(cert) = cert { + pubs.push(cert); + } + } + Ok(pubs) +} + fn parse_utf8(bytes: Vec) -> anyhow::Result { String::from_utf8(bytes).context("invalid utf-8") } @@ -122,3 +142,15 @@ pub async fn load_cert(file: impl AsRef + Debug) -> anyhow::Result + Debug) -> anyhow::Result> { + let contents = match fs::read(&file).await { + Ok(contents) => contents, + Err(e) if e.kind() == ErrorKind::NotFound => return Ok(None), + Err(e) => return Err(e).with_context(|| format!("read {:?}", &file)), + }; + let string_repr = parse_utf8(contents)?; + Ok(Some(PublicKey::from_openssh(&string_repr).with_context( + || format!("parse {:?} as openssh public key", &file), + )?)) +} diff --git a/common/src/lib.rs b/common/src/lib.rs new file mode 100644 index 0000000..af4e7dc --- /dev/null +++ b/common/src/lib.rs @@ -0,0 +1,6 @@ +mod certs; +mod routes; +mod util; + +pub use certs::*; +pub use routes::*; diff --git a/common/src/routes.rs b/common/src/routes.rs new file mode 100644 index 0000000..420ac29 --- /dev/null +++ b/common/src/routes.rs @@ -0,0 +1,41 @@ +use axum_extra::routing::TypedPath; + +use serde::{Deserialize, Serialize}; +use ssh_key::Fingerprint; + +#[derive(TypedPath, Deserialize)] +#[typed_path("/certs")] +pub struct CertList; + +#[derive(TypedPath, Deserialize)] +#[typed_path("/cert/:identifier")] +pub struct GetCert { + pub identifier: String, +} + +#[derive(TypedPath, Deserialize)] +#[typed_path("/certs/:pubkey_hash")] +pub struct GetCertsPubkey { + pub pubkey_hash: Fingerprint, +} + +#[derive(Debug, Serialize, Deserialize, Default)] +pub struct CertIds { + pub ids: Vec, +} + +#[derive(TypedPath, Deserialize)] +#[typed_path("/cert/:identifier/info")] +pub struct GetCertInfo { + pub identifier: String, +} + +#[derive(TypedPath, Deserialize)] +#[typed_path("/cert/:identifier")] +pub struct PostCertInfo { + pub identifier: String, +} + +#[derive(TypedPath)] +#[typed_path("/cert")] +pub struct PutCert; diff --git a/common/src/util.rs b/common/src/util.rs new file mode 100644 index 0000000..0a73400 --- /dev/null +++ b/common/src/util.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! env_key { + ( $var:expr ) => { + concat!("SSH_CD_", $var) + }; +} diff --git a/flake.lock b/flake.lock index 943419e..c5332da 100644 --- a/flake.lock +++ b/flake.lock @@ -7,11 +7,11 @@ ] }, "locked": { - "lastModified": 1662220400, - "narHash": "sha256-9o2OGQqu4xyLZP9K6kNe1pTHnyPz0Wr3raGYnr9AIgY=", + "lastModified": 1688534083, + "narHash": "sha256-/bI5vsioXscQTsx+Hk9X5HfweeNZz/6kVKsbdqfwW7g=", "owner": "nmattia", "repo": "naersk", - "rev": "6944160c19cb591eb85bbf9b2f2768a935623ed3", + "rev": "abca1fb7a6cfdd355231fc220c3d0302dbb4369a", "type": "github" }, "original": { @@ -22,11 +22,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1669411043, - "narHash": "sha256-LfPd3+EY+jaIHTRIEOUtHXuanxm59YKgUacmSzaqMLc=", + "lastModified": 1688679045, + "narHash": "sha256-t3xGEfYIwhaLTPU8FLtN/pLPytNeDwbLI6a7XFFBlGo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5dc7114b7b256d217fe7752f1614be2514e61bb8", + "rev": "3c7487575d9445185249a159046cc02ff364bff8", "type": "github" }, "original": { @@ -41,13 +41,31 @@ "utils": "utils" } }, - "utils": { + "systems": { "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index d87b6bf..ad44ce3 100644 --- a/flake.nix +++ b/flake.nix @@ -13,7 +13,7 @@ outputs = inputs @ { self, nixpkgs, utils, naersk, ... }: let root = inputs.source or self; - pname = (builtins.fromTOML (builtins.readFile (root + "/Cargo.toml"))).package.name; + pname = "ssh-cert-dist"; # toolchains: stable, beta, default(nightly) toolchain = pkgs: if inputs ? fenix then inputs.fenix.packages."${pkgs.system}".complete.toolchain @@ -24,15 +24,30 @@ in rec { # `nix build` - packages.${pname} = (self.overlay pkgs pkgs).${pname}; + packages."${pname}-server" = (self.overlay pkgs pkgs)."${pname}-server"; + packages."${pname}-client" = (self.overlay pkgs pkgs)."${pname}-client"; + + packages."${pname}-client-snap" = pkgs.snapTools.makeSnap { + meta = { + name = pname; + architectures = [ "amd64" ]; + confinement = "strict"; + apps.hello.command = apps."${pname}-client".program; + }; + }; packages.dockerImage = pkgs.runCommandLocal "docker-${pname}.tar.gz" { } "${apps.streamDockerImage.program} | gzip --fast > $out"; - packages.default = packages.${pname}; + packages.default = packages."${pname}-client"; # `nix run` - apps.${pname} = utils.lib.mkApp { - drv = packages.${pname}; + apps."${pname}-server" = utils.lib.mkApp { + drv = packages."${pname}-server"; + exePath = "/bin/sshcd-server"; + }; + apps."${pname}-client" = utils.lib.mkApp { + drv = packages."${pname}-client"; + exePath = "/bin/sshcd"; }; # `nix run .#streamDockerImage | docker load` @@ -41,12 +56,12 @@ name = pname; tag = self.shortRev or "latest"; config = { - Entrypoint = apps.default.program; + Entrypoint = apps."${pname}-server".program; }; }; exePath = ""; }; - apps.default = apps.${pname}; + apps.default = apps."${pname}-client"; # `nix flake check` checks = { @@ -78,7 +93,15 @@ rustc --version printf "\nbuild inputs: ${pkgs.lib.concatStringsSep ", " (map (bi: bi.name) (buildInputs ++ nativeBuildInputs))}" function server() { - cargo watch -x "run --all-features -- server ''${@}" + if [ ! -e "certs/ca.pub" ]; then + mkdir -p certs keys + ssh-keygen -t ed25519 -f certs/ca -q -N "" + ssh-keygen -t ed25519 -f keys/host -q -N "" + ssh-keygen -t ed25519 -f keys/client -q -N "" + ssh-keygen -s certs/ca -V +1000d -h -I host -n localhost,127.0.0.1 -h keys/host.pub + ssh-keygen -s certs/ca -V +1000d -I client -n "client,client@localhost" keys/client.pub -O force-command="echo Hello World" + fi + cargo watch -x "run --bin sshcd-server --all-features -- ''${@}" } ''; }; @@ -103,9 +126,15 @@ ]; in { - "${pname}" = + "${pname}-server" = naersk-lib.buildPackage { - inherit pname root buildInputs nativeBuildInputs; + name = "${pname}-server"; + inherit root buildInputs nativeBuildInputs; + }; + "${pname}-client" = + naersk-lib.buildPackage { + name = "${pname}-client"; + inherit root buildInputs nativeBuildInputs; }; }; diff --git a/modules/home-manager.nix b/modules/home-manager.nix index 64f3308..f78caa3 100644 --- a/modules/home-manager.nix +++ b/modules/home-manager.nix @@ -13,15 +13,14 @@ in Environment = "RUST_LOG=debug"; ExecStart = toString (pkgs.writeShellApplication { name = "ssh-cert-dist-${options.name}"; - runtimeInputs = [ pkgs.ssh-cert-dist ]; + runtimeInputs = [ cfg.package ]; text = '' ${optionalString options.fetch '' - ssh-cert-dist client fetch --cert-dir '${path}' --api-endpoint '${cfg.endpoint}' + sshcd fetch --cert-dir '${path}' --api-endpoint '${cfg.endpoint}' ''} ${optionalString options.upload '' - ssh-cert-dist client upload --api-endpoint '${cfg.endpoint}' ${path}/* + sshcd upload --api-endpoint '${cfg.endpoint}' ${path}/* ''} - ''; }); }; diff --git a/modules/nixos.nix b/modules/nixos.nix index e1d34b7..06697c1 100644 --- a/modules/nixos.nix +++ b/modules/nixos.nix @@ -14,7 +14,7 @@ in }; package = mkOption { type = types.package; - default = pkgs.ssh-cert-dist; + default = pkgs.ssh-cert-dist-server; }; ca = mkOption { type = types.path; @@ -57,7 +57,7 @@ in chown ${cfg.user}:${cfg.group} ${cfg.dataDir} ''}"; User = cfg.user; - ExecStart = "${cfg.package}/bin/ssh-cert-dist server"; + ExecStart = "${cfg.package}/bin/sshcd-server"; }; }; }; diff --git a/modules/options.nix b/modules/options.nix index 812d469..3fb8884 100644 --- a/modules/options.nix +++ b/modules/options.nix @@ -22,7 +22,7 @@ }; packageOption = mkOption { type = types.package; - default = pkgs.ssh-cert-dist; + default = pkgs.ssh-cert-dist-client; }; in diff --git a/server/Cargo.toml b/server/Cargo.toml new file mode 100644 index 0000000..2a87afe --- /dev/null +++ b/server/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "ssh-cert-dist-server" +version = "0.1.0" +authors = ["shimun "] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +default = [ "reload", "info", "authorized" ] +reload = [] +authorized =[ "dep:jwt-compact" ] +index = [] +info = [ "axum/json", "ssh-key/serde" ] + +[[bin]] +name = "sshcd-server" +path = "src/main.rs" + +[dependencies] +anyhow = "1.0.66" +async-trait = "0.1.59" +axum = { version = "0.6.1", features = ["http2"] } +axum-extra = { version = "0.4.1", features = ["typed-routing"] } +chrono = "0.4.23" +clap = { version = "4.0.29", features = ["env", "derive"] } +jwt-compact = { version = "0.6.0", features = ["serde_cbor", "std", "clock"], optional = true } +rand = "0.8.5" +serde = { version = "1.0.148", features = ["derive"] } +ssh-key = { version = "0.6.0-pre.0", features = ["ed25519", "p256", "p384", "rsa"] } +thiserror = "1.0.37" +tokio = { version = "1.22.0", features = ["io-std", "test-util", "tracing", "macros", "fs"] } +tower = { version = "0.4.13" } +tower-http = { version = "0.3.4", features = ["map-request-body", "trace", "util"] } +tracing = { version = "0.1.37", features = ["release_max_level_debug"] } +tracing-subscriber = "0.3.16" +ssh-cert-dist-common = { path = "../common" } +shell-escape = "0.1.5" + +[dev-dependencies] +tempfile = "3.3.0" + +[profile.release] +opt-level = 1 diff --git a/src/api.rs b/server/src/api.rs similarity index 71% rename from src/api.rs rename to server/src/api.rs index 517ac3a..576633b 100644 --- a/src/api.rs +++ b/server/src/api.rs @@ -1,35 +1,37 @@ mod extract; use std::collections::HashMap; +use std::fmt::Debug; + use std::net::SocketAddr; use std::path::{self, PathBuf}; use std::sync::Arc; -use std::time::{Duration, SystemTime}; +use std::time::{SystemTime, UNIX_EPOCH}; -use crate::certs::{load_cert_by_id, read_certs, read_pubkey, store_cert}; -use crate::env_key; use anyhow::Context; + use axum::body; +use axum::extract::rejection::QueryRejection; use axum::extract::{Query, State}; +use chrono::Duration; + +use shell_escape::escape; +use ssh_cert_dist_common::*; use axum::{http::StatusCode, response::IntoResponse, Json, Router}; -use axum_extra::routing::{ - RouterExt, // for `Router::typed_*` - TypedPath, -}; +use axum_extra::routing::RouterExt; use clap::{Args, Parser}; use jwt_compact::alg::{Hs256, Hs256Key}; -use jwt_compact::{AlgorithmExt, Token, UntrustedToken}; +use jwt_compact::{AlgorithmExt}; use rand::{thread_rng, Rng}; use serde::{Deserialize, Serialize}; -use ssh_key::private::Ed25519Keypair; -use ssh_key::{certificate, Certificate, PrivateKey, PublicKey}; +use ssh_key::{Certificate, Fingerprint, PublicKey}; use tokio::sync::Mutex; use tower::ServiceBuilder; use tower_http::{trace::TraceLayer, ServiceBuilderExt}; use tracing::{debug, info, trace}; -use self::extract::{CertificateBody, SignatureBody}; +use self::extract::{CertificateBody, SignatureBody, JWTAuthenticated, JWTString}; #[derive(Parser)] pub struct ApiArgs { @@ -77,7 +79,7 @@ impl Default for ApiArgs { } #[derive(Debug, Clone)] -struct ApiState { +pub struct ApiState { certs: Arc>>, cert_dir: PathBuf, ca: PublicKey, @@ -140,6 +142,7 @@ pub async fn run( let app = Router::new() .typed_get(get_certs_identifier) + .typed_get(get_certs_pubkey) .typed_put(put_cert_update) .typed_get(get_cert_info) .typed_post(post_certs_identifier); @@ -177,12 +180,23 @@ pub enum ApiError { AuthenticationRequired(String), #[error("invalid ssh signature")] InvalidSignature, + #[error("malformed ssh signature: {0}")] + ParseSignature(anyhow::Error), + #[error("malformed ssh certificate: {0}")] + ParseCertificate(anyhow::Error), + #[error("{0}")] + JWTParse(#[from] jwt_compact::ParseError), + #[error("{0}")] + JWTVerify(#[from] jwt_compact::ValidationError), + #[error("{0}")] + Query(#[from] QueryRejection), } type ApiResult = Result; impl IntoResponse for ApiError { fn into_response(self) -> axum::response::Response { + trace!({ error = ?self }, "returned error for request"); ( match self { Self::CertificateNotFound => StatusCode::NOT_FOUND, @@ -202,10 +216,7 @@ async fn fallback_404() -> ApiResult<()> { Err(ApiError::CertificateNotFound) } -#[derive(TypedPath, Deserialize)] -#[typed_path("/certs")] -pub struct CertList; - +#[cfg(feature = "index")] async fn list_certs( _: CertList, State(ApiState { certs, .. }): State, @@ -221,16 +232,26 @@ async fn list_certs( )) } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "aud", rename = "get")] struct AuthClaims { identifier: String, } -#[derive(TypedPath, Deserialize)] -#[typed_path("/certs/:identifier")] -pub struct GetCert { - pub identifier: String, +async fn request_client_auth(enabled: bool, identifier: &str, jwt_key: &Hs256Key) -> ApiResult<()> { + use jwt_compact::{Claims, Header, TimeOptions}; + if enabled { + let claims = Claims::new(AuthClaims { + identifier: identifier.into(), + }) + .set_duration(&TimeOptions::default(), chrono::Duration::seconds(120)); + let challenge = Hs256 + .compact_token(Header::default(), &claims, &jwt_key) + .context("jwt sign")?; + return Err(ApiError::AuthenticationRequired(challenge)); + } else { + Ok(()) + } } /// Retrieve an certificate for identifier @@ -247,16 +268,7 @@ async fn get_certs_identifier( .. }): State, ) -> ApiResult { - use jwt_compact::{AlgorithmExt, Claims, Header, TimeOptions}; - - if client_auth { - let claims = Claims::new(AuthClaims { identifier }) - .set_duration(&TimeOptions::default(), chrono::Duration::seconds(120)); - let challenge = Hs256 - .compact_token(Header::default(), &claims, &jwt_key) - .context("jwt sign")?; - return Err(ApiError::AuthenticationRequired(challenge)); - } + request_client_auth(client_auth, &identifier, &jwt_key).await?; let certs = certs.lock().await; let cert = certs .get(&identifier) @@ -264,10 +276,22 @@ async fn get_certs_identifier( Ok(cert.to_openssh().context("to openssh")?) } -#[derive(TypedPath, Deserialize)] -#[typed_path("/certs/:identifier/info")] -pub struct GetCertInfo { - pub identifier: String, +async fn get_certs_pubkey( + GetCertsPubkey { pubkey_hash }: GetCertsPubkey, + State(ApiState { + certs, + jwt_key: _, + client_auth: _, + .. + }): State, +) -> ApiResult> { + let certs = certs.lock().await; + let ids = certs + .values() + .filter(|cert| &cert.public_key().fingerprint(pubkey_hash.algorithm()) == &pubkey_hash) + .map(|cert| cert.key_id().to_string()) + .collect::>(); + Ok(Json(CertIds { ids })) } #[cfg(feature = "info")] @@ -275,19 +299,59 @@ pub struct GetCertInfo { struct CertInfo { principals: Vec, ca: PublicKey, + ca_hash: Fingerprint, identity: PublicKey, + identity_hash: Fingerprint, key_id: String, expiry: SystemTime, + renew_command: String, } impl From<&Certificate> for CertInfo { fn from(cert: &Certificate) -> Self { + let validity = cert + .valid_before_time() + .duration_since(cert.valid_after_time()) + .unwrap_or(Duration::zero().to_std().unwrap()); + let expiry = cert.valid_before_time().checked_add(validity).unwrap(); + let expiry_date = expiry.duration_since(UNIX_EPOCH).unwrap(); + let host_key = if cert.cert_type().is_host() { + " -h" + } else { + "" + }; + let opts = cert + .critical_options() + .iter() + .map(|(opt, val)| { + if val.is_empty() { + opt.clone() + } else { + format!("{opt}={val}") + } + }) + .map(|arg| format!("-O {}", escape(arg.into()))) + .collect::>() + .join(" "); + let opts = opts.trim(); + let renew_command = format!( + "ssh-keygen -s ./ca_key {host_key} -I {} -n {} -z {} -V {:#x}:{:#x} {opts} {}.pub", + escape(cert.key_id().into()), + escape(cert.valid_principals().join(",").into()), + cert.serial() + 1, + cert.valid_after(), + expiry_date.as_secs(), + escape(cert.key_id().into()) + ); CertInfo { principals: cert.valid_principals().to_vec(), ca: cert.signature_key().clone().into(), + ca_hash: cert.signature_key().fingerprint(ssh_key::HashAlg::Sha256), identity: cert.public_key().clone().into(), + identity_hash: cert.public_key().fingerprint(ssh_key::HashAlg::Sha256), key_id: cert.key_id().to_string(), expiry: cert.valid_before_time(), + renew_command, } } } @@ -312,33 +376,31 @@ async fn get_cert_info( unimplemented!() } -#[derive(TypedPath, Deserialize)] -#[typed_path("/certs/:identifier")] -pub struct PostCertInfo { - pub identifier: String, -} - #[derive(Debug, Deserialize)] struct PostCertsQuery { challenge: String, } +impl From> for JWTString { + fn from(Query(PostCertsQuery { challenge }): Query) -> Self { + Self::from(challenge) + } +} + + /// POST with signed challenge async fn post_certs_identifier( PostCertInfo { identifier }: PostCertInfo, - State(ApiState { certs, jwt_key, .. }): State, + State(ApiState { certs, .. }): State, + JWTAuthenticated { + data: auth_claims, .. + }: JWTAuthenticated>, Query(PostCertsQuery { challenge }): Query, SignatureBody(sig): SignatureBody, ) -> ApiResult { let certs = certs.lock().await; let cert = certs.get(&identifier).ok_or(ApiError::InvalidSignature)?; - let token: Token = Hs256 - .validate_integrity( - &UntrustedToken::new(&challenge).context("jwt parse")?, - &jwt_key, - ) - .map_err(|_| ApiError::InvalidSignature)?; - if token.claims().custom.identifier != identifier { + if auth_claims.identifier != identifier { return Err(ApiError::InvalidSignature); } let pubkey: PublicKey = cert.public_key().clone().into(); @@ -353,10 +415,6 @@ async fn post_certs_identifier( Ok(cert.to_openssh().context("to openssh")?) } -#[derive(TypedPath)] -#[typed_path("/cert")] -pub struct PutCert; - /// Upload an cert with an higher serial than the previous async fn put_cert_update( _: PutCert, @@ -405,12 +463,14 @@ async fn put_cert_update( let identity = cert.key_id(); info!(%identity, ?principals, "updating certificate"); certs.lock().await.insert(cert.key_id().to_string(), cert); - Ok(format!("{} -> {}", prev_serial, serial)) + Ok(format!("{prev_serial} -> {serial}")) } #[cfg(test)] mod tests { + use ssh_key::{certificate, private::Ed25519Keypair, PrivateKey}; use std::env::temp_dir; + use std::time::Duration; use super::*; @@ -423,14 +483,23 @@ mod tests { } fn ca_pub() -> PublicKey { - PublicKey::new(ca_key().public.into(), "TEST CA") + PublicKey::new( + ca_key().public.into(), + format!( + "TEST CA {}", + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs() + ), + ) } fn user_key() -> Ed25519Keypair { Ed25519Keypair::from_seed(&[1u8; 32]) } - fn user_cert(ca: Ed25519Keypair, user_key: PublicKey) -> Certificate { + fn user_cert(ca: Ed25519Keypair, user_key: PublicKey, validity: Duration) -> Certificate { let ca_private: PrivateKey = ca.into(); let unix_time = |time: SystemTime| -> u64 { time.duration_since(SystemTime::UNIX_EPOCH) @@ -441,7 +510,7 @@ mod tests { [0u8; 16], user_key, unix_time(SystemTime::now()), - unix_time(SystemTime::now() + Duration::from_secs(30)), + unix_time(SystemTime::now() + validity), ); builder @@ -449,7 +518,7 @@ mod tests { .unwrap() .key_id("test_cert") .unwrap() - .comment("A TEST CERT") + .comment(&format!("A TEST CERT, VALID FOR {}s", validity.as_secs())) .unwrap(); builder.sign(&ca_private).unwrap() @@ -463,24 +532,49 @@ mod tests { cert_dir: dbg!(temp_dir()), validation_args: Default::default(), client_auth: false, - jwt_key: Hs256Key::new(&[0u8; 16]), + jwt_key: Hs256Key::new([0u8; 16]), } } #[test] fn test_certificate() { - let valid_cert = user_cert(ca_key(), user_key().public.into()); + let valid_cert = user_cert(ca_key(), user_key().public.into(), Duration::from_secs(30)); let ca_pub: PublicKey = ca_pub(); assert!(valid_cert .validate(&[ca_pub.fingerprint(Default::default())]) .is_ok()); } + #[tokio::test] + async fn update_cert() { + let state = api_state(); + let ca = ca_key(); + let user: PublicKey = user_key().public.into(); + let (cert_first, cert_newer, cert_outdated) = { + ( + user_cert(ca.clone(), user.clone(), Duration::from_secs(300)), + user_cert(ca.clone(), user.clone(), Duration::from_secs(600)), + user_cert(ca.clone(), user.clone(), Duration::from_secs(30)), + ) + }; + let res = put_cert_update(PutCert, State(state.clone()), CertificateBody(cert_first)).await; + assert!(dbg!(res).is_ok()); + let res = put_cert_update(PutCert, State(state.clone()), CertificateBody(cert_newer)).await; + assert!(res.is_ok()); + let res = put_cert_update( + PutCert, + State(state.clone()), + CertificateBody(cert_outdated), + ) + .await; + assert!(res.is_err()); + } + #[tokio::test] async fn routes() -> anyhow::Result<()> { let state = api_state(); - let valid_cert = user_cert(ca_key(), user_key().public.into()); - let invalid_cert = user_cert(ca_key2(), user_key().public.into()); + let valid_cert = user_cert(ca_key(), user_key().public.into(), Duration::from_secs(30)); + let invalid_cert = user_cert(ca_key2(), user_key().public.into(), Duration::from_secs(30)); let res = put_cert_update( PutCert, State(state.clone()), @@ -537,6 +631,9 @@ mod tests { identifier: "test_cert".into(), }, State(state.clone()), + JWTAuthenticated::new(AuthClaims { + identifier: "test_cert".into(), + }), Query(PostCertsQuery { challenge }), SignatureBody(sig), ) diff --git a/server/src/api/extract.rs b/server/src/api/extract.rs new file mode 100644 index 0000000..4ea447e --- /dev/null +++ b/server/src/api/extract.rs @@ -0,0 +1,123 @@ +use std::fmt::Debug; +use std::marker::PhantomData; + +use super::{ApiError, ApiState}; +use anyhow::Context; +use axum::{ + async_trait, + body::BoxBody, + extract::{FromRequest, FromRequestParts}, + http::Request, +}; +use jwt_compact::{alg::Hs256, AlgorithmExt, Token, UntrustedToken}; +use serde::{de::DeserializeOwned, Serialize}; +use ssh_key::{Certificate, SshSig}; +use tracing::trace; + +#[derive(Debug, Clone)] +pub struct CertificateBody(pub Certificate); + +// we must implement `FromRequest` (and not `FromRequestParts`) to consume the body +#[async_trait] +impl FromRequest for CertificateBody +where + S: Send + Sync, +{ + type Rejection = ApiError; + + async fn from_request(req: Request, state: &S) -> Result { + let body = String::from_request(req, state) + .await + .context("failed to extract body")?; + + let cert = Certificate::from_openssh(&body) + .with_context(|| format!("failed to parse '{}'", body)) + .map_err(ApiError::ParseCertificate)?; + trace!(%body, "extracted certificate"); + Ok(Self(cert)) + } +} + +#[derive(Debug, Clone)] +pub struct SignatureBody(pub SshSig); + +#[async_trait] +impl FromRequest for SignatureBody +where + S: Send + Sync, +{ + type Rejection = ApiError; + + async fn from_request(req: Request, state: &S) -> Result { + let body = String::from_request(req, state) + .await + .context("failed to extract body")?; + + let sig = SshSig::from_pem(&body) + .with_context(|| format!("failed to parse '{}'", body)) + .map_err(ApiError::ParseSignature)?; + trace!(%body, "extracted signature"); + Ok(Self(sig)) + } +} + +pub struct JWTString(String); + +impl From for JWTString { + fn from(s: String) -> Self { + Self(s) + } +} + +// TODO: be generic over ApiState -> AsRef, AsRef where A: AlgorithmExt +#[derive(Debug)] +pub struct JWTAuthenticated< + T: Serialize + DeserializeOwned + Clone + Debug, + Q: FromRequestParts + Debug + Into, +> where + ApiError: From<>::Rejection>, +{ + pub data: T, + _marker: PhantomData, +} + +impl< + T: Serialize + DeserializeOwned + Clone + Debug, + Q: FromRequestParts + Debug + Into, + > JWTAuthenticated +where + ApiError: From<>::Rejection>, +{ + pub fn new(data: T) -> Self { + Self { + data, + _marker: Default::default(), + } + } +} + +#[async_trait] +impl< + T: Serialize + DeserializeOwned + Clone + Debug, + Q: FromRequestParts + Debug + Into, + > FromRequestParts for JWTAuthenticated +where + ApiError: From<>::Rejection>, +{ + type Rejection = ApiError; + + async fn from_request_parts( + parts: &mut axum::http::request::Parts, + state: &ApiState, + ) -> Result { + let JWTString(token) = Q::from_request_parts(parts, state).await?.into(); + let token = UntrustedToken::new(&token).map_err(ApiError::JWTParse)?; + let verified: Token = Hs256 + .validate_integrity(&token, &state.jwt_key) + .map_err(ApiError::JWTVerify)?; + Ok(Self { + data: verified.claims().custom.clone(), + _marker: Default::default(), + }) + } +} diff --git a/server/src/main.rs b/server/src/main.rs new file mode 100644 index 0000000..dbaeb77 --- /dev/null +++ b/server/src/main.rs @@ -0,0 +1,10 @@ +use clap::Parser; + +mod api; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> anyhow::Result<()> { + tracing_subscriber::fmt::init(); + + api::run(api::ApiArgs::parse()).await +} diff --git a/src/api/extract.rs b/src/api/extract.rs deleted file mode 100644 index 4b9ef79..0000000 --- a/src/api/extract.rs +++ /dev/null @@ -1,51 +0,0 @@ -use anyhow::Context; -use axum::{ - async_trait, body::BoxBody, extract::FromRequest, http::Request, response::IntoResponse, -}; -use ssh_key::{Certificate, SshSig}; -use tracing::trace; -use super::ApiError; - -#[derive(Debug, Clone)] -pub struct CertificateBody(pub Certificate); - -// we must implement `FromRequest` (and not `FromRequestParts`) to consume the body -#[async_trait] -impl FromRequest for CertificateBody -where - S: Send + Sync, -{ - type Rejection = ApiError; - - async fn from_request(req: Request, state: &S) -> Result { - let body = String::from_request(req, state) - .await - .context("failed to extract body")?; - - let cert = Certificate::from_openssh(&body) - .with_context(|| format!("failed to parse '{}'", body))?; - trace!(%body, "extracted certificate"); - Ok(Self(cert)) - } -} - -#[derive(Debug, Clone)] -pub struct SignatureBody(pub SshSig); - -#[async_trait] -impl FromRequest for SignatureBody -where - S: Send + Sync, -{ - type Rejection = ApiError; - - async fn from_request(req: Request, state: &S) -> Result { - let body = String::from_request(req, state) - .await - .context("failed to extract body")?; - - let sig = SshSig::from_pem(&body).with_context(|| format!("failed to parse '{}'", body))?; - trace!(%body, "extracted signature"); - Ok(Self(sig)) - } -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e3185a6..0000000 --- a/src/main.rs +++ /dev/null @@ -1,35 +0,0 @@ -use api::ApiArgs; -use clap::Parser; -#[cfg(feature = "client")] -use client::ClientCommand; - -mod api; -mod certs; -#[cfg(feature = "client")] -mod client; - -#[macro_export] -macro_rules! env_key { - ( $var:expr ) => { - concat!("SSH_CD_", $var) - }; -} - -#[derive(Parser)] -enum Command { - Server(ApiArgs), - #[cfg(feature = "client")] - Client(ClientCommand), -} - -#[tokio::main(flavor = "current_thread")] -async fn main() -> anyhow::Result<()> { - tracing_subscriber::fmt::init(); - - match Command::parse() { - Command::Server(args) => api::run(args).await?, - #[cfg(feature = "client")] - Command::Client(args) => client::run(args).await?, - } - Ok(()) -}