diff --git a/Cargo.lock b/Cargo.lock index ac229258..a1d276f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,6 +18,16 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "aead" +version = "0.6.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b657e772794c6b04730ea897b66a058ccd866c16d1967da05eeeecec39043fe" +dependencies = [ + "crypto-common 0.2.1", + "inout 0.2.2", +] + [[package]] name = "aes" version = "0.8.4" @@ -25,21 +35,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures 0.2.17", ] +[[package]] +name = "aes" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" +dependencies = [ + "cipher 0.5.1", + "cpubits", + "cpufeatures 0.3.0", +] + [[package]] name = "aes-gcm" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", + "aead 0.5.2", + "aes 0.8.4", + "cipher 0.4.4", + "ctr 0.9.2", + "ghash 0.5.1", + "subtle", +] + +[[package]] +name = "aes-gcm" +version = "0.11.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22c0c90bbe8d4f77c3ca9ddabe41a1f8382d6fc1f7cea89459d0f320371f972" +dependencies = [ + "aead 0.6.0-rc.10", + "aes 0.9.0", + "cipher 0.5.1", + "ctr 0.10.0", + "ghash 0.6.0", "subtle", ] @@ -301,7 +336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" dependencies = [ "blowfish", - "pbkdf2", + "pbkdf2 0.12.2", "sha2 0.10.9", ] @@ -359,7 +394,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" dependencies = [ - "hybrid-array 0.4.10", + "hybrid-array", ] [[package]] @@ -371,6 +406,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-padding" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710f1dd022ef4e93f8a438b4ba958de7f64308434fa6a87104481645cc30068b" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block2" version = "0.6.2" @@ -387,7 +431,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" dependencies = [ "byteorder", - "cipher", + "cipher 0.4.4", ] [[package]] @@ -427,7 +471,7 @@ dependencies = [ "opentelemetry-otlp", "opentelemetry_sdk", "owo-colors", - "rand 0.9.3", + "rand 0.10.1", "ratatui", "regex", "rpassword", @@ -463,62 +507,67 @@ dependencies = [ [[package]] name = "bssh-russh" -version = "0.59.0" +version = "0.60.0" dependencies = [ - "aes", + "aes 0.8.4", "async-trait", "aws-lc-rs", "bitflags 2.11.0", - "block-padding", + "block-padding 0.3.3", "byteorder", "bytes", - "cbc", - "ctr", + "cbc 0.1.2", + "cipher 0.5.1", + "crypto-bigint 0.7.3", + "ctr 0.9.2", "curve25519-dalek", "data-encoding", "delegate", - "der 0.7.10", + "der 0.8.0", "des", "digest 0.10.7", - "ecdsa", + "ecdsa 0.17.0-rc.16", "ed25519-dalek", - "elliptic-curve", + "elliptic-curve 0.14.0-rc.30", "enum_dispatch", "flate2", "futures", "generic-array 1.3.5", "getrandom 0.2.17", "hex-literal", - "hmac", - "inout", + "hmac 0.12.1", + "inout 0.1.4", "internal-russh-forked-ssh-key", + "internal-russh-num-bigint", "log", "md5", "ml-kem", - "num-bigint", - "p256", - "p384", - "p521", - "pbkdf2", + "module-lattice", + "p256 0.14.0-rc.8", + "p384 0.14.0-rc.8", + "p521 0.14.0-rc.8", + "pbkdf2 0.12.2", "pkcs1 0.8.0-rc.4", "pkcs5", - "pkcs8 0.10.2", - "rand 0.9.3", - "rand_core 0.10.0-rc-3", + "pkcs8 0.11.0-rc.11", + "polyval 0.7.1", + "rand 0.10.1", + "rand_core 0.10.0", "ring", - "rsa 0.10.0-rc.12", + "rsa 0.10.0-rc.17", "russh-cryptovec", "russh-util", - "sec1", + "sec1 0.8.1", "sha1 0.10.6", "sha2 0.10.9", - "signature 2.2.0", - "spki 0.7.3", + "signature 3.0.0-rc.10", + "spki 0.8.0", "ssh-encoding", "subtle", "thiserror 2.0.18", "tokio", "typenum", + "universal-hash 0.6.1", "yasna", "zeroize", ] @@ -568,7 +617,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "cbc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98db6aeaef0eeef2c1e3ce9a27b739218825dae116076352ac3777076aa22225" +dependencies = [ + "cipher 0.5.1", ] [[package]] @@ -602,10 +660,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures 0.2.17", ] +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.0", +] + [[package]] name = "chrono" version = "0.4.44" @@ -654,7 +723,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common 0.1.7", - "inout", + "inout 0.1.4", +] + +[[package]] +name = "cipher" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +dependencies = [ + "block-buffer 0.12.0", + "crypto-common 0.2.1", + "inout 0.2.2", ] [[package]] @@ -717,9 +797,9 @@ dependencies = [ [[package]] name = "cmov" -version = "0.5.0-pre.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5417da527aa9bf6a1e10a781231effd1edd3ee82f27d5f8529ac9b279babce96" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" [[package]] name = "colorchoice" @@ -836,6 +916,12 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpubits" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -970,14 +1056,18 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-rc.18" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37387ceb32048ff590f2cbd24d8b05fffe63c3f69a5cfa089d4f722ca4385a19" +checksum = "42a0d26b245348befa0c121944541476763dcc46ede886c88f9d12e1697d27c3" dependencies = [ + "cpubits", "ctutils", + "getrandom 0.4.2", + "hybrid-array", "num-traits", - "rand_core 0.10.0-rc-3", + "rand_core 0.10.0", "serdect", + "subtle", "zeroize", ] @@ -997,18 +1087,20 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" dependencies = [ - "hybrid-array 0.4.10", + "getrandom 0.4.2", + "hybrid-array", + "rand_core 0.10.0", ] [[package]] name = "crypto-primes" -version = "0.7.0-pre.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79c98a281f9441200b24e3151407a629bfbe720399186e50516da939195e482" +checksum = "21f41f23de7d24cdbda7f0c4d9c0351f99a4ceb258ef30e5c1927af8987ffe5a" dependencies = [ - "crypto-bigint 0.7.0-rc.18", + "crypto-bigint 0.7.3", "libm", - "rand_core 0.10.0-rc-3", + "rand_core 0.10.0", ] [[package]] @@ -1027,7 +1119,16 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "ctr" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17469f8eb9bdbfad10f71f4cfddfd38b01143520c0e717d8796ccb4d44d44e42" +dependencies = [ + "cipher 0.5.1", ] [[package]] @@ -1043,23 +1144,24 @@ dependencies = [ [[package]] name = "ctutils" -version = "0.3.2" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758e5ed90be3c8abff7f9a6f37ab7f6d8c59c2210d448b81f3f508134aec84e4" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" dependencies = [ "cmov", + "subtle", ] [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "335f1947f241137a14106b6f5acc5918a5ede29c9d71d3f2cb1678d5075d9fc3" dependencies = [ "cfg-if", "cpufeatures 0.2.17", "curve25519-dalek-derive", - "digest 0.10.7", + "digest 0.11.2", "fiat-crypto", "rustc_version", "subtle", @@ -1141,7 +1243,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid 0.9.6", - "pem-rfc7468 0.7.0", "zeroize", ] @@ -1193,7 +1294,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" dependencies = [ - "cipher", + "cipher 0.4.4", ] [[package]] @@ -1217,6 +1318,7 @@ dependencies = [ "block-buffer 0.12.0", "const-oid 0.10.2", "crypto-common 0.2.1", + "ctutils", ] [[package]] @@ -1289,17 +1391,17 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "dsa" -version = "0.6.3" +version = "0.7.0-rc.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48bc224a9084ad760195584ce5abb3c2c34a225fa312a128ad245a6b412b7689" +checksum = "205b3f37ceb87c2ed5c72dac75f286848c68b19ba3246e9196f3666ce048a14b" dependencies = [ - "digest 0.10.7", - "num-bigint-dig", - "num-traits", - "pkcs8 0.10.2", - "rfc6979", - "sha2 0.10.9", - "signature 2.2.0", + "crypto-bigint 0.7.3", + "crypto-primes", + "der 0.8.0", + "digest 0.11.2", + "rfc6979 0.5.0-rc.5", + "sha2 0.11.0", + "signature 3.0.0-rc.10", "zeroize", ] @@ -1317,33 +1419,49 @@ checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der 0.7.10", "digest 0.10.7", - "elliptic-curve", - "rfc6979", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", "signature 2.2.0", "spki 0.7.3", ] +[[package]] +name = "ecdsa" +version = "0.17.0-rc.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91bbdd377139884fafcad8dc43a760a3e1e681aa26db910257fa6535b70e1829" +dependencies = [ + "der 0.8.0", + "digest 0.11.2", + "elliptic-curve 0.14.0-rc.30", + "rfc6979 0.5.0-rc.5", + "signature 3.0.0-rc.10", + "spki 0.8.0", + "zeroize", +] + [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "c6e914c7c52decb085cea910552e24c63ac019e3ab8bf001ff736da9a9d9d890" dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", + "pkcs8 0.11.0-rc.11", + "signature 3.0.0-rc.10", ] [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "053618a4c3d3bc24f188aa660ae75a46eeab74ef07fb415c61431e5e7cd4749b" dependencies = [ "curve25519-dalek", "ed25519", - "rand_core 0.6.4", + "rand_core 0.10.0", "serde", - "sha2 0.10.9", + "sha2 0.11.0", + "signature 3.0.0-rc.10", "subtle", "zeroize", ] @@ -1366,11 +1484,32 @@ dependencies = [ "ff", "generic-array 0.14.7", "group", - "hkdf", - "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.14.0-rc.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d7a0bfd012613a7bcfe02cbfccf2b846e9ef9e1bccb641c48d461253cfb034d" +dependencies = [ + "base16ct 1.0.0", + "crypto-bigint 0.7.3", + "crypto-common 0.2.1", + "digest 0.11.2", + "hkdf", + "hybrid-array", + "once_cell", + "pem-rfc7468 1.0.0", + "pkcs8 0.11.0-rc.11", + "rand_core 0.10.0", + "rustcrypto-ff", + "rustcrypto-group", + "sec1 0.8.1", "subtle", "zeroize", ] @@ -1458,9 +1597,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "filedescriptor" @@ -1699,6 +1838,7 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", + "rand_core 0.10.0", "wasip2", "wasip3", ] @@ -1710,7 +1850,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", - "polyval", + "polyval 0.6.2", +] + +[[package]] +name = "ghash" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5" +dependencies = [ + "polyval 0.7.1", ] [[package]] @@ -1821,11 +1970,11 @@ checksum = "e712f64ec3850b98572bffac52e2c6f282b29fe6c5fa6d42334b30be438d95c1" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ - "hmac", + "hmac 0.13.0", ] [[package]] @@ -1837,6 +1986,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.2", +] + [[package]] name = "home" version = "0.5.12" @@ -1891,22 +2049,16 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hybrid-array" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" -dependencies = [ - "typenum", -] - [[package]] name = "hybrid-array" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" dependencies = [ + "ctutils", + "subtle", "typenum", + "zeroize", ] [[package]] @@ -2146,10 +2298,20 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "block-padding", + "block-padding 0.3.3", "generic-array 0.14.7", ] +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "block-padding 0.4.2", + "hybrid-array", +] + [[package]] name = "insta" version = "1.47.2" @@ -2177,37 +2339,47 @@ dependencies = [ [[package]] name = "internal-russh-forked-ssh-key" -version = "0.6.16+upstream-0.6.7" +version = "0.6.18+upstream-0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe44f2bbd99fcb302e246e2d6bcf51aeda346d02a365f80296a07a8c711b6da6" +checksum = "25f8a978272e3cbdf4768f7363eb1c8e1e6ba63c52a3ed05e29e222da4aec7cb" dependencies = [ "argon2", "bcrypt-pbkdf", - "digest 0.11.2", + "crypto-bigint 0.7.3", "dsa", - "ecdsa", + "ecdsa 0.17.0-rc.16", "ed25519-dalek", "hex", - "hmac", + "hmac 0.13.0", "num-bigint-dig", - "p256", - "p384", - "p521", - "rand_core 0.6.4", - "rsa 0.10.0-rc.12", - "sec1", + "p256 0.14.0-rc.8", + "p384 0.14.0-rc.8", + "p521 0.14.0-rc.8", + "rand_core 0.10.0", + "rsa 0.10.0-rc.17", + "sec1 0.8.1", "serde", - "sha1 0.10.6", "sha1 0.11.0", - "sha2 0.10.9", - "signature 2.2.0", - "signature 3.0.0-rc.6", + "sha2 0.11.0", + "signature 3.0.0-rc.10", "ssh-cipher", "ssh-encoding", "subtle", "zeroize", ] +[[package]] +name = "internal-russh-num-bigint" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8e22120c32fb4d19ec55fba35015f57095cd95a2e3b732e44457f5915b2ee8" +dependencies = [ + "num-integer", + "num-traits", + "rand 0.10.1", + "rand_core 0.10.0", +] + [[package]] name = "ipnet" version = "2.12.0" @@ -2295,21 +2467,22 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.6" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa" dependencies = [ - "cpufeatures 0.2.17", + "cfg-if", + "cpufeatures 0.3.0", ] [[package]] name = "kem" -version = "0.3.0-pre.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8645470337db67b01a7f966decf7d0bafedbae74147d33e641c67a91df239f" +checksum = "01737161ba802849cfd486b5bd209d38ba4943494c249a8126005170c7621edd" dependencies = [ - "rand_core 0.6.4", - "zeroize", + "crypto-common 0.2.1", + "rand_core 0.10.0", ] [[package]] @@ -2481,13 +2654,14 @@ dependencies = [ [[package]] name = "ml-kem" -version = "0.2.3" +version = "0.3.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de49b3df74c35498c0232031bb7e85f9389f913e2796169c8ab47a53993a18f" +checksum = "04437cb1a66c0b78740927b76cc61f218344b9f6ef3dd430e283274a718ef0e9" dependencies = [ - "hybrid-array 0.2.3", + "hybrid-array", "kem", - "rand_core 0.6.4", + "module-lattice", + "rand_core 0.10.0", "sha3", ] @@ -2542,6 +2716,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "module-lattice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eb3faeaecbd14b0b2a917c1b4d0c035097a9c559b0bed85c2cdd032bc8faa" +dependencies = [ + "ctutils", + "hybrid-array", + "num-traits", +] + [[package]] name = "nibble_vec" version = "0.1.0" @@ -2603,7 +2788,6 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", - "rand 0.8.5", ] [[package]] @@ -2855,24 +3039,51 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder 0.13.6", "sha2 0.10.9", ] +[[package]] +name = "p256" +version = "0.14.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f0a10fe314869359cb2901342b045f4e5a962ef9febc006f03d2a8c848fe4c" +dependencies = [ + "ecdsa 0.17.0-rc.16", + "elliptic-curve 0.14.0-rc.30", + "primefield", + "primeorder 0.14.0-rc.8", + "sha2 0.11.0", +] + [[package]] name = "p384" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder 0.13.6", "sha2 0.10.9", ] +[[package]] +name = "p384" +version = "0.14.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b079e66810c55ab3d6ba424e056dc4aefcdb8046c8c3f3816142edbdd7af7721" +dependencies = [ + "ecdsa 0.17.0-rc.16", + "elliptic-curve 0.14.0-rc.30", + "fiat-crypto", + "primefield", + "primeorder 0.14.0-rc.8", + "sha2 0.11.0", +] + [[package]] name = "p521" version = "0.13.3" @@ -2880,13 +3091,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" dependencies = [ "base16ct 0.2.0", - "ecdsa", - "elliptic-curve", - "primeorder", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder 0.13.6", "rand_core 0.6.4", "sha2 0.10.9", ] +[[package]] +name = "p521" +version = "0.14.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eecc34c4c6e6596d5271fecf90ac4f16593fa198e77282214d0c22736aa9266" +dependencies = [ + "base16ct 1.0.0", + "ecdsa 0.17.0-rc.16", + "elliptic-curve 0.14.0-rc.30", + "primefield", + "primeorder 0.14.0-rc.8", + "sha2 0.11.0", +] + [[package]] name = "page_size" version = "0.6.0" @@ -2938,7 +3163,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "pbkdf2" +version = "0.13.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f24f3eb2f4471b1730d59e4b730b747939960a8c7eb0c33c5a9076f2d3dddea" +dependencies = [ + "digest 0.11.2", + "hmac 0.13.0", ] [[package]] @@ -3109,17 +3344,19 @@ dependencies = [ [[package]] name = "pkcs5" -version = "0.7.1" +version = "0.8.0-rc.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +checksum = "c5a777c6e26664bc9504b3ce3f6133f8f20d9071f130a4f9fcbd3186959d8dd6" dependencies = [ - "aes", - "cbc", - "der 0.7.10", - "pbkdf2", + "aes 0.9.0", + "aes-gcm 0.11.0-rc.3", + "cbc 0.2.0", + "der 0.8.0", + "pbkdf2 0.13.0-rc.10", + "rand_core 0.10.0", "scrypt", - "sha2 0.10.9", - "spki 0.7.3", + "sha2 0.11.0", + "spki 0.8.0", ] [[package]] @@ -3129,8 +3366,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.10", - "pkcs5", - "rand_core 0.6.4", "spki 0.7.3", ] @@ -3141,6 +3376,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" dependencies = [ "der 0.8.0", + "pkcs5", + "rand_core 0.10.0", "spki 0.8.0", ] @@ -3180,7 +3417,7 @@ checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures 0.2.17", "opaque-debug", - "universal-hash", + "universal-hash 0.5.1", ] [[package]] @@ -3192,7 +3429,18 @@ dependencies = [ "cfg-if", "cpufeatures 0.2.17", "opaque-debug", - "universal-hash", + "universal-hash 0.5.1", +] + +[[package]] +name = "polyval" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfc63250416fea14f5749b90725916a6c903f599d51cb635aa7a52bfd03eede" +dependencies = [ + "cpubits", + "cpufeatures 0.3.0", + "universal-hash 0.6.1", ] [[package]] @@ -3261,13 +3509,36 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "primefield" +version = "0.14.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6543f5eec854fbf74ba5ef651fbdc9408919b47c3e1526623687135c16d12e9" +dependencies = [ + "crypto-bigint 0.7.3", + "crypto-common 0.2.1", + "rand_core 0.10.0", + "rustcrypto-ff", + "subtle", + "zeroize", +] + [[package]] name = "primeorder" version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.8", +] + +[[package]] +name = "primeorder" +version = "0.14.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "569d9ad6ef822bb0322c7e7d84e5e286244050bd5246cac4c013535ae91c2c90" +dependencies = [ + "elliptic-curve 0.14.0-rc.30", ] [[package]] @@ -3354,6 +3625,17 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20 0.10.0", + "getrandom 0.4.2", + "rand_core 0.10.0", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -3394,9 +3676,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.10.0-rc-3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66ee92bc15280519ef199a274fe0cafff4245d31bc39aaa31c011ad56cb1f05" +checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" [[package]] name = "ratatui" @@ -3592,7 +3874,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", + "subtle", +] + +[[package]] +name = "rfc6979" +version = "0.5.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23a3127ee32baec36af75b4107082d9bd823501ec14a4e016be4b6b37faa74ae" +dependencies = [ + "hmac 0.13.0", "subtle", ] @@ -3644,19 +3936,19 @@ dependencies = [ [[package]] name = "rsa" -version = "0.10.0-rc.12" +version = "0.10.0-rc.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a2b1eacbc34fbaf77f6f1db1385518446008d49b9f9f59dc9d1340fce4ca9e" +checksum = "87ed3e93fc7e473e464b9726f4759659e72bc8665e4b8ea227547024f416d905" dependencies = [ "const-oid 0.10.2", - "crypto-bigint 0.7.0-rc.18", + "crypto-bigint 0.7.3", "crypto-primes", "digest 0.11.2", "pkcs1 0.8.0-rc.4", "pkcs8 0.11.0-rc.11", - "rand_core 0.10.0-rc-3", + "rand_core 0.10.0", "sha2 0.11.0", - "signature 3.0.0-rc.6", + "signature 3.0.0-rc.10", "spki 0.8.0", "zeroize", ] @@ -3721,6 +4013,27 @@ dependencies = [ "semver", ] +[[package]] +name = "rustcrypto-ff" +version = "0.14.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd2a8adb347447693cd2ba0d218c4b66c62da9b0a5672b17b981e4291ec65ff6" +dependencies = [ + "rand_core 0.10.0", + "subtle", +] + +[[package]] +name = "rustcrypto-group" +version = "0.14.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "369f9b61aa45933c062c9f6b5c3c50ab710687eca83dd3802653b140b43f85ed" +dependencies = [ + "rand_core 0.10.0", + "rustcrypto-ff", + "subtle", +] + [[package]] name = "rustix" version = "1.1.4" @@ -3817,11 +4130,12 @@ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "salsa20" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +checksum = "2f874456e72520ff1375a06c588eaf074b0f01f9e9e1aada45bd9b7954a6e42c" dependencies = [ - "cipher", + "cfg-if", + "cipher 0.5.1", ] [[package]] @@ -3859,13 +4173,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scrypt" -version = "0.11.0" +version = "0.12.0-rc.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +checksum = "e03ed5b54ed5fcc8e016cd94301416bc2c01c05c87a6742b97468337c8804598" dependencies = [ - "pbkdf2", + "cfg-if", + "pbkdf2 0.13.0-rc.10", "salsa20", - "sha2 0.10.9", + "sha2 0.11.0", ] [[package]] @@ -3888,6 +4203,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sec1" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" +dependencies = [ + "base16ct 1.0.0", + "ctutils", + "der 0.8.0", + "hybrid-array", + "subtle", + "zeroize", +] + [[package]] name = "secrecy" version = "0.10.3" @@ -4083,11 +4412,11 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.8" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1" dependencies = [ - "digest 0.10.7", + "digest 0.11.2", "keccak", ] @@ -4165,12 +4494,12 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.6" +version = "3.0.0-rc.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a96996ccff7dfa16f052bd995b4cecc72af22c35138738dc029f0ead6608d" +checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3" dependencies = [ "digest 0.11.2", - "rand_core 0.10.0-rc-3", + "rand_core 0.10.0", ] [[package]] @@ -4245,12 +4574,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" dependencies = [ - "aes", - "aes-gcm", - "cbc", - "chacha20", - "cipher", - "ctr", + "aes 0.8.4", + "aes-gcm 0.10.3", + "cbc 0.1.2", + "chacha20 0.9.1", + "cipher 0.4.4", + "ctr 0.9.2", "poly1305", "ssh-encoding", "subtle", @@ -4274,12 +4603,12 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b86f5297f0f04d08cabaa0f6bff7cb6aec4d9c3b49d87990d63da9d9156a8c3" dependencies = [ - "p256", - "p384", - "p521", + "p256 0.13.2", + "p384 0.13.1", + "p521 0.13.3", "rand_core 0.6.4", "rsa 0.9.10", - "sec1", + "sec1 0.7.3", "sha2 0.10.9", "signature 2.2.0", "ssh-cipher", @@ -4855,6 +5184,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "universal-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" +dependencies = [ + "crypto-common 0.2.1", + "ctutils", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" diff --git a/Cargo.toml b/Cargo.toml index 9a46ffa0..c481c7aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ tokio = { version = "1.51.1", features = ["full"] } # Use our internal russh fork with session loop fixes # - Development: uses local path (crates/bssh-russh) # - Publishing: uses crates.io version (path ignored) -russh = { package = "bssh-russh", version = "0.59", path = "crates/bssh-russh" } +russh = { package = "bssh-russh", version = "0.60", path = "crates/bssh-russh" } russh-sftp = "2.1.1" clap = { version = "4.6.0", features = ["derive", "env"] } anyhow = "1.0.102" @@ -67,7 +67,7 @@ libc = "0.2" ipnetwork = "0.21" bcrypt = "0.19" argon2 = "0.5" -rand = "0.9" +rand = "0.10" ssh-key = { version = "0.6", features = ["std"] } async-compression = { version = "0.4", features = ["tokio", "gzip"] } serde_json = "1.0" diff --git a/crates/bssh-russh/Cargo.toml b/crates/bssh-russh/Cargo.toml index 4c12b19d..46867d96 100644 --- a/crates/bssh-russh/Cargo.toml +++ b/crates/bssh-russh/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bssh-russh" -version = "0.59.0" +version = "0.60.0" authors = ["Jeongkyu Shin "] description = "Temporary fork of russh with high-frequency PTY output fix (Handle::data from spawned tasks)" documentation = "https://docs.rs/bssh-russh" @@ -31,17 +31,19 @@ bitflags = "2.0" block-padding = { version = "0.3", features = ["std"] } byteorder = "1.4" bytes = "1.7" -cbc = "0.1" +cbc = { version = "0.1" } +cipher = "0.5.1" ctr = "0.9" -curve25519-dalek = "4.1.3" +curve25519-dalek = "5.0.0-pre.6" +crypto-bigint = { version = "0.7.0-rc.28", features = ["alloc"] } data-encoding = "2.3" delegate = "0.13" digest = "0.10" -der = "0.7" +der = "0.8" des = { version = "0.8.1", optional = true } -ecdsa = "0.16" -ed25519-dalek = { version = "2.0", features = ["rand_core", "pkcs8"] } -elliptic-curve = { version = "0.13", features = ["ecdh"] } +ecdsa = "0.17.0-rc.16" +ed25519-dalek = { version = "3.0.0-pre.6", features = ["alloc", "rand_core", "pkcs8"] } +elliptic-curve = { version = "0.14.0-rc.28", features = ["ecdh"] } enum_dispatch = "0.3.13" flate2 = { version = "1.0.15", optional = true } futures = "0.3" @@ -52,29 +54,34 @@ hmac = "0.12" inout = { version = "0.1", features = ["std"] } log = "0.4" md5 = "0.7" -ml-kem = "0.2.3" -num-bigint = { version = "0.4.2", features = ["rand"] } -p256 = { version = "0.13", features = ["ecdh"] } -p384 = { version = "0.13", features = ["ecdh"] } -p521 = { version = "0.13", features = ["ecdh"] } +ml-kem = "0.3.0-rc.1" +module-lattice = "0.2" +# num-bigint 0.4.x only supports rand 0.8; upstream russh ships a fork that +# adds rand 0.10 support via the `rand_0_10` feature flag. +num-bigint = { package = "internal-russh-num-bigint", version = "=0.5.0", features = ["rand_0_10"] } +p256 = { version = "0.14.0-rc.7", features = ["ecdh"] } +p384 = { version = "0.14.0-rc.7", features = ["ecdh"] } +p521 = { version = "0.14.0-rc.7", features = ["ecdh"] } pbkdf2 = "0.12" pkcs1 = { version = "0.8.0-rc.4", optional = true } -pkcs5 = "0.7" -pkcs8 = { version = "0.10", features = ["pkcs5", "encryption", "std"] } -rand_core = { version = "=0.10.0-rc-3" } -rand = { version = "0.9", features = ["thread_rng"] } +pkcs5 = "0.8.0-rc.13" +pkcs8 = { version = "0.11.0-rc.11", features = ["encryption", "std"] } +polyval = "0.7.1" +rand_core = { version = "0.10.0" } +rand = { version = "0.10", features = ["thread_rng"] } ring = { version = "0.17.14", optional = true } rsa = { version = "0.10.0-rc.10", optional = true } -sec1 = { version = "0.7", features = ["pkcs8", "der"] } +sec1 = { version = "0.8", features = ["der"] } sha1 = { version = "0.10.5", features = ["oid"] } sha2 = { version = "0.10.6", features = ["oid"] } -signature = "2.2" -spki = "0.7" +signature = "3.0.0-rc.10" +spki = "0.8.0-rc.4" ssh-encoding = { version = "0.2", features = ["bytes"] } subtle = "2.4" thiserror = "2.0.18" -tokio = { version = "1.50.0", features = ["io-util", "sync", "time", "rt-multi-thread", "net"] } +tokio = { version = "1.51.1", features = ["io-util", "sync", "time", "rt-multi-thread", "net"] } typenum = "1.17" +universal-hash = "0.6.1" yasna = { version = "0.5.0", features = ["bit-vec", "num-bigint"], optional = true } zeroize = "1.7" @@ -83,7 +90,7 @@ russh-cryptovec = { version = "0.59.0", features = ["ssh-encoding"] } russh-util = "0.52.0" # Use the forked ssh-key from russh -ssh-key = { version = "=0.6.16", features = [ +ssh-key = { version = "=0.6.18", features = [ "ed25519", "p256", "p384", diff --git a/crates/bssh-russh/src/cipher/benchmark.rs b/crates/bssh-russh/src/cipher/benchmark.rs index 16193f4a..85511cb0 100644 --- a/crates/bssh-russh/src/cipher/benchmark.rs +++ b/crates/bssh-russh/src/cipher/benchmark.rs @@ -1,10 +1,10 @@ #![allow(clippy::unwrap_used)] use criterion::*; -use rand::TryRngCore; +use rand_core::TryRng; use std::hint; pub fn bench(c: &mut Criterion) { - let mut rand_generator = hint::black_box(rand::rngs::OsRng {}); + let mut rand_generator = hint::black_box(rand::rng()); let mut packet_length = hint::black_box(vec![0u8; 4]); diff --git a/crates/bssh-russh/src/cipher/block.rs b/crates/bssh-russh/src/cipher/block.rs index e321ec99..523f411c 100644 --- a/crates/bssh-russh/src/cipher/block.rs +++ b/crates/bssh-russh/src/cipher/block.rs @@ -17,7 +17,7 @@ use std::marker::PhantomData; use aes::cipher::{IvSizeUser, KeyIvInit, KeySizeUser, StreamCipher}; #[allow(deprecated)] use digest::generic_array::GenericArray as GenericArray_0_14; -use rand::RngCore; +use rand_core::Rng; use super::super::Error; use super::PACKET_LENGTH_LEN; diff --git a/crates/bssh-russh/src/cipher/gcm.rs b/crates/bssh-russh/src/cipher/gcm.rs index 5c4d4260..9afbdbb3 100644 --- a/crates/bssh-russh/src/cipher/gcm.rs +++ b/crates/bssh-russh/src/cipher/gcm.rs @@ -25,7 +25,7 @@ use aws_lc_rs::{ }, error::Unspecified, }; -use rand::RngCore; +use rand_core::Rng; #[cfg(all(not(feature = "aws-lc-rs"), feature = "ring"))] use ring::{ aead::{ diff --git a/crates/bssh-russh/src/client/kex.rs b/crates/bssh-russh/src/client/kex.rs index 73512833..d6523318 100644 --- a/crates/bssh-russh/src/client/kex.rs +++ b/crates/bssh-russh/src/client/kex.rs @@ -5,19 +5,18 @@ use std::sync::Arc; use bytes::Bytes; use log::{debug, error, warn}; -use signature::Verifier; use ssh_encoding::{Decode, Encode}; use ssh_key::{Mpint, PublicKey, Signature}; use super::IncomingSshPacket; use crate::client::{Config, NewKeys}; use crate::kex::dh::groups::DhGroup; -use crate::kex::{KexAlgorithm, KexAlgorithmImplementor, KexCause, KexProgress, KEXES}; +use crate::kex::{KEXES, KexAlgorithm, KexAlgorithmImplementor, KexCause, KexProgress}; use crate::keys::key::parse_public_key; use crate::negotiation::{Names, Select}; use crate::session::Exchange; use crate::sshbuffer::PacketWriter; -use crate::{msg, negotiation, strict_kex_violation, CryptoVec, Error, SshId}; +use crate::{CryptoVec, Error, SshId, msg, negotiation, strict_kex_violation}; thread_local! { static HASH_BUFFER: RefCell = RefCell::new(CryptoVec::new()); @@ -116,7 +115,9 @@ impl ClientKex { let names = { // read algorithms from packet. - self.exchange.server_kex_init.extend_from_slice(&input.buffer); + self.exchange + .server_kex_init + .extend_from_slice(&input.buffer); negotiation::Client::read_kex( &input.buffer, &self.config.preferred, @@ -270,7 +271,9 @@ impl ClientKex { ); let server_ephemeral = Bytes::decode(r)?; - self.exchange.server_ephemeral.extend_from_slice(&server_ephemeral); + self.exchange + .server_ephemeral + .extend_from_slice(&server_ephemeral); kex.compute_shared_secret(&self.exchange.server_ephemeral)?; let mut pubkey_vec = Vec::new(); @@ -288,7 +291,9 @@ impl ClientKex { let signature = Bytes::decode(r)?; let signature = Signature::decode(&mut &signature[..])?; - if let Err(e) = Verifier::verify(&server_host_key, hash.as_ref(), &signature) { + if let Err(e) = + signature::Verifier::verify(&server_host_key, hash.as_ref(), &signature) + { debug!("wrong server sig: {e:?}"); return Err(Error::WrongServerSig); } diff --git a/crates/bssh-russh/src/client/mod.rs b/crates/bssh-russh/src/client/mod.rs index e1e99565..5f2e5088 100644 --- a/crates/bssh-russh/src/client/mod.rs +++ b/crates/bssh-russh/src/client/mod.rs @@ -1685,22 +1685,42 @@ impl GexParams { preferred_group_size: usize, max_group_size: usize, ) -> Result { - let this = Self { + Self::for_client_config(min_group_size, preferred_group_size, max_group_size) + } + + pub fn for_client_config( + min_group_size: usize, + preferred_group_size: usize, + max_group_size: usize, + ) -> Result { + Self::build( min_group_size, preferred_group_size, max_group_size, - }; - this.validate()?; - Ok(this) - } - - pub(crate) fn validate(&self) -> Result<(), Error> { - if self.min_group_size < 2048 { - return Err(Error::InvalidConfig(format!( - "min_group_size must be at least 2048 bits. We got {} bits", - self.min_group_size - ))); + ValidationKind::ClientConfig, + ) + } + + fn validate(&self, kind: ValidationKind) -> Result<(), Error> { + match kind { + ValidationKind::ClientConfig => { + if self.min_group_size < 2048 { + return Err(Error::InvalidConfig(format!( + "min_group_size must be at least 2048 bits. We got {} bits", + self.min_group_size + ))); + } + } + ValidationKind::PeerRequest => { + if self.max_group_size < 2048 { + return Err(Error::InvalidConfig(format!( + "max_group_size must be at least 2048 bits. We got {} bits", + self.max_group_size + ))); + } + } } + if self.preferred_group_size < self.min_group_size { return Err(Error::InvalidConfig(format!( "preferred_group_size must be at least as large as min_group_size. We have preferred_group_size = {} < min_group_size = {}", @@ -1713,9 +1733,38 @@ impl GexParams { self.max_group_size, self.preferred_group_size ))); } + Ok(()) } + pub(crate) fn from_peer_request( + min_group_size: usize, + preferred_group_size: usize, + max_group_size: usize, + ) -> Result { + Self::build( + min_group_size, + preferred_group_size, + max_group_size, + ValidationKind::PeerRequest, + ) + } + + fn build( + min_group_size: usize, + preferred_group_size: usize, + max_group_size: usize, + kind: ValidationKind, + ) -> Result { + let this = Self { + min_group_size, + preferred_group_size, + max_group_size, + }; + this.validate(kind)?; + Ok(this) + } + pub fn min_group_size(&self) -> usize { self.min_group_size } @@ -1729,6 +1778,12 @@ impl GexParams { } } +#[derive(Clone, Copy, Eq, PartialEq)] +enum ValidationKind { + ClientConfig, + PeerRequest, +} + impl Default for GexParams { fn default() -> GexParams { GexParams { diff --git a/crates/bssh-russh/src/client/test.rs b/crates/bssh-russh/src/client/test.rs index 54746718..94069a12 100644 --- a/crates/bssh-russh/src/client/test.rs +++ b/crates/bssh-russh/src/client/test.rs @@ -10,7 +10,7 @@ mod tests { // Import client types directly since we're in the client module use crate::client::{Config, Handler, connect}; use crate::keys::PrivateKeyWithHashAlg; - use crate::keys::ssh_key::rand_core::OsRng; + use rand::rng; use crate::server::{self, Auth, Handler as ServerHandler, Server, Session}; use crate::{ChannelId, SshId}; // Import directly from crate root use crate::Error; @@ -82,7 +82,7 @@ mod tests { let _ = env_logger::try_init(); // Create a client key - let client_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let client_key = PrivateKey::random(&mut rng(), ssh_key::Algorithm::Ed25519).unwrap(); // Configure the server let mut config = server::Config::default(); @@ -91,7 +91,7 @@ mod tests { config.inactivity_timeout = None; config .keys - .push(PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap()); + .push(PrivateKey::random(&mut rng(), ssh_key::Algorithm::Ed25519).unwrap()); let config = Arc::new(config); // Create server struct diff --git a/crates/bssh-russh/src/kex/dh/groups.rs b/crates/bssh-russh/src/kex/dh/groups.rs index 8ee65baa..cb3bcabe 100644 --- a/crates/bssh-russh/src/kex/dh/groups.rs +++ b/crates/bssh-russh/src/kex/dh/groups.rs @@ -1,9 +1,8 @@ use std::fmt::Debug; use std::ops::Deref; -use crate::keys::ssh_key::rand_core::OsRng; use hex_literal::hex; -use num_bigint::{BigUint, RandBigInt}; +use num_bigint::{BigRng010, BigUint}; #[derive(Clone)] pub enum DhGroupUInt { @@ -282,9 +281,9 @@ impl DH { pub fn generate_private_key(&mut self, is_server: bool) -> BigUint { let q = (&self.prime_num - &BigUint::from(1u8)) / &BigUint::from(2u8); - let mut rng = OsRng; + let mut rng = rand::rng(); self.private_key = - rng.gen_biguint_range(&if is_server { 1u8.into() } else { 2u8.into() }, &q); + rng.random_biguint_range(&if is_server { 1u8.into() } else { 2u8.into() }, &q); self.private_key.clone() } diff --git a/crates/bssh-russh/src/kex/dh/mod.rs b/crates/bssh-russh/src/kex/dh/mod.rs index 701ceaac..730a2f2e 100644 --- a/crates/bssh-russh/src/kex/dh/mod.rs +++ b/crates/bssh-russh/src/kex/dh/mod.rs @@ -347,7 +347,7 @@ impl Decode for GexParams { let min_group_size = u32::decode(reader)? as usize; let preferred_group_size = u32::decode(reader)? as usize; let max_group_size = u32::decode(reader)? as usize; - GexParams::new(min_group_size, preferred_group_size, max_group_size) + GexParams::from_peer_request(min_group_size, preferred_group_size, max_group_size) } type Error = Error; diff --git a/crates/bssh-russh/src/kex/ecdh_nistp.rs b/crates/bssh-russh/src/kex/ecdh_nistp.rs index a7a8b76e..335f2c64 100644 --- a/crates/bssh-russh/src/kex/ecdh_nistp.rs +++ b/crates/bssh-russh/src/kex/ecdh_nistp.rs @@ -1,11 +1,11 @@ use std::marker::PhantomData; use std::ops::Deref; -use crate::keys::ssh_key::rand_core::OsRng; use byteorder::{BigEndian, ByteOrder}; +use elliptic_curve::Generate; use elliptic_curve::ecdh::{EphemeralSecret, SharedSecret}; use elliptic_curve::point::PointCompression; -use elliptic_curve::sec1::{FromEncodedPoint, ModulusSize, ToEncodedPoint}; +use elliptic_curve::sec1::{FromSec1Point, ModulusSize, ToSec1Point}; use elliptic_curve::{AffinePoint, Curve, CurveArithmetic, FieldBytesSize}; use log::debug; use p256::NistP256; @@ -79,7 +79,7 @@ impl KexAlgorithmImplementor for EcdhNist where C: PointCompression, FieldBytesSize: ModulusSize, - AffinePoint: FromEncodedPoint + ToEncodedPoint, + AffinePoint: FromSec1Point + ToSec1Point, { fn skip_exchange(&self) -> bool { false @@ -106,7 +106,7 @@ where .map_err(|_| crate::Error::Inconsistent)? }; - let server_secret = elliptic_curve::ecdh::EphemeralSecret::::random(&mut OsRng); + let server_secret = elliptic_curve::ecdh::EphemeralSecret::::generate_from_rng(&mut rand::rng()); let server_pubkey = server_secret.public_key(); // fill exchange. @@ -125,7 +125,7 @@ where client_ephemeral: &mut Vec, writer: &mut impl Writer, ) -> Result<(), crate::Error> { - let client_secret = elliptic_curve::ecdh::EphemeralSecret::::random(&mut OsRng); + let client_secret = elliptic_curve::ecdh::EphemeralSecret::::generate_from_rng(&mut rand::rng()); let client_pubkey = client_secret.public_key(); // fill exchange. @@ -214,14 +214,14 @@ mod tests { #[test] fn test_shared_secret() { let mut party1 = EcdhNistPKex:: { - local_secret: Some(EphemeralSecret::::random(&mut OsRng)), + local_secret: Some(EphemeralSecret::::generate_from_rng(&mut rand::rng())), shared_secret: None, _digest: PhantomData, }; let p1_pubkey = party1.local_secret.as_ref().unwrap().public_key(); let mut party2 = EcdhNistPKex:: { - local_secret: Some(EphemeralSecret::::random(&mut OsRng)), + local_secret: Some(EphemeralSecret::::generate_from_rng(&mut rand::rng())), shared_secret: None, _digest: PhantomData, }; diff --git a/crates/bssh-russh/src/kex/hybrid_mlkem.rs b/crates/bssh-russh/src/kex/hybrid_mlkem.rs index 8a94e8d1..421f1205 100644 --- a/crates/bssh-russh/src/kex/hybrid_mlkem.rs +++ b/crates/bssh-russh/src/kex/hybrid_mlkem.rs @@ -3,15 +3,16 @@ use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE; use curve25519_dalek::montgomery::MontgomeryPoint; use curve25519_dalek::scalar::Scalar; use log::debug; +use ml_kem::Kem; use ml_kem::{ - EncodedSizeUser, KemCore, MlKem768, MlKem768Params, + MlKem768, kem::{Decapsulate, DecapsulationKey, Encapsulate, EncapsulationKey}, + KeyExport, TryKeyInit, }; use sha2::Digest; use ssh_encoding::{Encode, Writer}; use super::{KexAlgorithm, KexAlgorithmImplementor, KexType, SharedSecret, compute_keys}; -use crate::keys::ssh_key::rand_core::OsRng; use crate::mac; use crate::session::Exchange; use crate::{CryptoVec, Error, cipher, msg}; @@ -20,8 +21,8 @@ const MLKEM768_PUBLIC_KEY_SIZE: usize = 1184; const MLKEM768_CIPHERTEXT_SIZE: usize = 1088; const X25519_PUBLIC_KEY_SIZE: usize = 32; -type MlKem768PublicKey = EncapsulationKey; -type MlKem768PrivateKey = DecapsulationKey; +type MlKem768PublicKey = EncapsulationKey; +type MlKem768PrivateKey = DecapsulationKey; type MlKem768Ciphertext = ml_kem::Ciphertext; pub struct MlKem768X25519KexType {} @@ -42,7 +43,7 @@ impl KexType for MlKem768X25519KexType { pub struct MlKem768X25519Kex { mlkem_secret: Option>, x25519_secret: Option, - k_pq: Option>, + k_pq: Option, k_cl: Option, } @@ -86,15 +87,12 @@ impl KexAlgorithmImplementor for MlKem768X25519Kex { #[allow(clippy::indexing_slicing)] let c_pk1_bytes = &c_init[MLKEM768_PUBLIC_KEY_SIZE..]; - let c_pk2_array = - ml_kem::Encoded::::try_from(c_pk2_bytes).map_err(|_| Error::Kex)?; - let c_pk2 = MlKem768PublicKey::from_bytes(&c_pk2_array); + let c_pk2 = MlKem768PublicKey::new_from_slice(c_pk2_bytes).map_err(|_| Error::Kex)?; let mut c_pk1 = MontgomeryPoint([0; 32]); c_pk1.0.copy_from_slice(c_pk1_bytes); - let (s_ct2, k_pq_shared_secret) = - c_pk2.encapsulate(&mut OsRng).map_err(|_| Error::KexInit)?; + let (s_ct2, k_pq_shared_secret) = c_pk2.encapsulate_with_rng(&mut rand::rng()); let s_secret = Scalar::from_bytes_mod_order(rand::random::<[u8; 32]>()); let s_pk1 = (ED25519_BASEPOINT_TABLE * &s_secret).to_montgomery(); @@ -118,18 +116,18 @@ impl KexAlgorithmImplementor for MlKem768X25519Kex { client_ephemeral: &mut Vec, writer: &mut impl Writer, ) -> Result<(), Error> { - let (mlkem_sk, mlkem_pk) = MlKem768::generate(&mut OsRng); + let (mlkem_sk, mlkem_pk) = MlKem768::generate_keypair_from_rng(&mut rand::rng()); let x25519_secret = Scalar::from_bytes_mod_order(rand::random::<[u8; 32]>()); let x25519_pk = (ED25519_BASEPOINT_TABLE * &x25519_secret).to_montgomery(); client_ephemeral.clear(); - client_ephemeral.extend(&mlkem_pk.as_bytes()); + client_ephemeral.extend(&mlkem_pk.to_bytes()); client_ephemeral.extend(&x25519_pk.0); msg::KEX_HYBRID_INIT.encode(writer)?; let mut c_init = Vec::::new(); - c_init.extend(mlkem_pk.as_bytes()); + c_init.extend(mlkem_pk.to_bytes()); c_init.extend(&x25519_pk.0); c_init.as_slice().encode(writer)?; @@ -152,10 +150,7 @@ impl KexAlgorithmImplementor for MlKem768X25519Kex { let s_ct2 = MlKem768Ciphertext::try_from(s_ct2_bytes).map_err(|_| Error::KexInit)?; let mlkem_secret = self.mlkem_secret.take().ok_or(Error::KexInit)?; - let k_pq_shared_secret = mlkem_secret - .decapsulate(&s_ct2) - .map_err(|_| Error::KexInit)?; - + let k_pq_shared_secret = mlkem_secret.decapsulate(&s_ct2); let mut s_pk1 = MontgomeryPoint([0; 32]); s_pk1.0.copy_from_slice(s_pk1_bytes); diff --git a/crates/bssh-russh/src/keys/agent/mod.rs b/crates/bssh-russh/src/keys/agent/mod.rs index af3beaec..433535da 100644 --- a/crates/bssh-russh/src/keys/agent/mod.rs +++ b/crates/bssh-russh/src/keys/agent/mod.rs @@ -83,17 +83,16 @@ impl AgentIdentity { #[cfg(test)] mod tests { use super::*; - use ssh_key::rand_core::OsRng; use ssh_key::{PrivateKey, certificate}; fn create_test_certificate() -> Certificate { use std::time::{SystemTime, UNIX_EPOCH}; // Create a CA key - let ca_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let ca_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); // Create a user key to be certified - let user_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let user_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); // Build and sign the certificate with reasonable validity window let now = SystemTime::now() @@ -104,7 +103,7 @@ mod tests { let valid_before = now + 86400 * 365; // 1 year from now let mut builder = certificate::Builder::new_with_random_nonce( - &mut OsRng, + &mut rand::rng(), user_key.public_key(), valid_after, valid_before, @@ -120,7 +119,7 @@ mod tests { #[test] fn test_agent_identity_public_key_variant() { - let key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519) + let key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519) .unwrap() .public_key() .clone(); @@ -161,7 +160,7 @@ mod tests { #[test] fn test_agent_identity_clone() { - let key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519) + let key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519) .unwrap() .public_key() .clone(); @@ -177,7 +176,7 @@ mod tests { #[test] fn test_agent_identity_debug() { - let key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519) + let key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519) .unwrap() .public_key() .clone(); diff --git a/crates/bssh-russh/src/keys/format/pkcs8.rs b/crates/bssh-russh/src/keys/format/pkcs8.rs index 78eb1e11..3eff91fc 100644 --- a/crates/bssh-russh/src/keys/format/pkcs8.rs +++ b/crates/bssh-russh/src/keys/format/pkcs8.rs @@ -3,7 +3,7 @@ use std::convert::{TryFrom, TryInto}; use p256::NistP256; use p384::NistP384; use p521::NistP521; -use pkcs8::{AssociatedOid, EncodePrivateKey, PrivateKeyInfo, SecretDocument}; +use pkcs8::{AssociatedOid, EncodePrivateKey, PrivateKeyInfoRef, SecretDocument}; use spki::ObjectIdentifier; use ssh_key::PrivateKey; use ssh_key::private::{EcdsaKeypair, Ed25519Keypair, Ed25519PrivateKey, KeypairData}; @@ -18,7 +18,7 @@ pub fn decode_pkcs8( ) -> Result { let doc = SecretDocument::try_from(ciphertext)?; let doc = if let Some(password) = password { - doc.decode_msg::()? + doc.decode_msg::>()? .decrypt(password)? } else { doc @@ -35,12 +35,15 @@ pub fn decode_pkcs8( } Err(_) => { // ASN.1 key - Ok(pkcs8_pki_into_keypair_data(doc.decode_msg::()?)?.try_into()?) + Ok( + pkcs8_pki_into_keypair_data(doc.decode_msg::>()?)? + .try_into()?, + ) } } } -fn pkcs8_pki_into_keypair_data(pki: PrivateKeyInfo<'_>) -> Result { +fn pkcs8_pki_into_keypair_data(pki: PrivateKeyInfoRef<'_>) -> Result { // Temporary if {} due to multiple const_oid crate versions #[cfg(feature = "rsa")] if pki.algorithm.oid.as_bytes() == pkcs1::ALGORITHM_OID.as_bytes() { @@ -116,9 +119,9 @@ pub fn encode_pkcs8_encrypted( key: &PrivateKey, ) -> Result, Error> { let pvi_bytes = encode_pkcs8(key)?; - let pvi = PrivateKeyInfo::try_from(pvi_bytes.as_slice())?; + let pvi = PrivateKeyInfoRef::try_from(pvi_bytes.as_slice())?; - use rand::RngCore; + use rand_core::Rng; let mut rng = safe_rng(); let mut salt = [0; 64]; rng.fill_bytes(&mut salt); @@ -126,7 +129,7 @@ pub fn encode_pkcs8_encrypted( rng.fill_bytes(&mut iv); let doc = pvi.encrypt_with_params( - pkcs5::pbes2::Parameters::pbkdf2_sha256_aes256cbc(rounds, &salt, &iv) + pkcs5::pbes2::Parameters::pbkdf2_sha256_aes256cbc(rounds, &salt, iv) .map_err(|_| Error::InvalidParameters)?, pass, )?; @@ -148,15 +151,15 @@ pub fn encode_pkcs8(key: &ssh_key::PrivateKey) -> Result, Error> { } ssh_key::private::KeypairData::Ecdsa(pair) => match pair { EcdsaKeypair::NistP256 { private, .. } => { - let sk = p256::SecretKey::from_bytes(private.as_slice().into())?; + let sk = p256::SecretKey::from_slice(private.as_slice())?; sk.to_pkcs8_der()?.as_bytes().to_vec() } EcdsaKeypair::NistP384 { private, .. } => { - let sk = p384::SecretKey::from_bytes(private.as_slice().into())?; + let sk = p384::SecretKey::from_slice(private.as_slice())?; sk.to_pkcs8_der()?.as_bytes().to_vec() } EcdsaKeypair::NistP521 { private, .. } => { - let sk = p521::SecretKey::from_bytes(private.as_slice().into())?; + let sk = p521::SecretKey::from_slice(private.as_slice())?; sk.to_pkcs8_der()?.as_bytes().to_vec() } }, diff --git a/crates/bssh-russh/src/keys/mod.rs b/crates/bssh-russh/src/keys/mod.rs index 21e011bf..44c539c7 100644 --- a/crates/bssh-russh/src/keys/mod.rs +++ b/crates/bssh-russh/src/keys/mod.rs @@ -158,9 +158,6 @@ pub enum Error { Pkcs1(#[from] pkcs1::Error), #[error("Pkcs8: {0}")] Pkcs8(#[from] ::pkcs8::Error), - #[cfg(feature = "rsa")] - #[error("Pkcs8: {0}")] - Pkcs8Next(#[from] ::rsa::pkcs8::Error), #[error("Sec1: {0}")] Sec1(#[from] sec1::Error), @@ -1023,8 +1020,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux #[cfg(unix)] fn create_test_cert(ca_key: &PrivateKey, user_key: &PrivateKey) -> ssh_key::Certificate { use ssh_key::certificate; - use ssh_key::rand_core::OsRng; - use std::time::{SystemTime, UNIX_EPOCH}; + use std::time::{SystemTime, UNIX_EPOCH}; let now = SystemTime::now() .duration_since(UNIX_EPOCH) @@ -1034,7 +1030,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux let valid_before = now + 86400 * 365; // 1 year from now let mut builder = certificate::Builder::new_with_random_nonce( - &mut OsRng, + &mut rand::rng(), user_key.public_key(), valid_after, valid_before, @@ -1052,8 +1048,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux #[cfg(unix)] async fn test_request_identities_full_with_keys_and_certs() { use crate::keys::agent::{AgentIdentity, client::AgentClient}; - use ssh_key::rand_core::OsRng; - use std::io::Write; + use std::io::Write; use std::process::Stdio; env_logger::try_init().unwrap_or(()); @@ -1061,9 +1056,9 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux let (mut agent, agent_path, dir) = spawn_agent().await.unwrap(); // Create a CA key and user key - let ca_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); - let user_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); - let plain_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let ca_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); + let user_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); + let plain_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); // Create a certificate let cert = create_test_cert(&ca_key, &user_key); @@ -1179,8 +1174,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux #[cfg(unix)] async fn test_sign_request_cert() { use crate::keys::agent::client::AgentClient; - use ssh_key::rand_core::OsRng; - use std::io::Write; + use std::io::Write; use std::process::Stdio; env_logger::try_init().unwrap_or(()); @@ -1188,8 +1182,8 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux let (mut agent, agent_path, dir) = spawn_agent().await.unwrap(); // Create a CA key and user key - let ca_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); - let user_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let ca_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); + let user_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); // Create a certificate let cert = create_test_cert(&ca_key, &user_key); @@ -1257,15 +1251,14 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux #[cfg(unix)] async fn test_sign_request_cert_missing_key_returns_agent_failure() { use crate::keys::agent::client::AgentClient; - use ssh_key::rand_core::OsRng; - + env_logger::try_init().unwrap_or(()); let (mut agent, agent_path, _dir) = spawn_agent().await.unwrap(); // Create a CA key and user key, but DON'T add them to the agent - let ca_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); - let user_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let ca_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); + let user_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); // Create a certificate let cert = create_test_cert(&ca_key, &user_key); @@ -1310,14 +1303,13 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux #[cfg(unix)] async fn test_sign_request_missing_key_returns_agent_failure() { use crate::keys::agent::client::AgentClient; - use ssh_key::rand_core::OsRng; - + env_logger::try_init().unwrap_or(()); let (mut agent, agent_path, _dir) = spawn_agent().await.unwrap(); // Create a key but DON'T add it to the agent - let key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); // Connect to agent WITHOUT adding any keys let stream = tokio::net::UnixStream::connect(&agent_path).await.unwrap(); @@ -1361,8 +1353,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux #[cfg(all(unix, feature = "rsa"))] fn create_test_rsa_cert(ca_key: &PrivateKey, user_key: &PrivateKey) -> ssh_key::Certificate { use ssh_key::certificate; - use ssh_key::rand_core::OsRng; - use std::time::{SystemTime, UNIX_EPOCH}; + use std::time::{SystemTime, UNIX_EPOCH}; let now = SystemTime::now() .duration_since(UNIX_EPOCH) @@ -1372,7 +1363,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux let valid_before = now + 86400 * 365; // 1 year from now let mut builder = certificate::Builder::new_with_random_nonce( - &mut OsRng, + &mut rand::rng(), user_key.public_key(), valid_after, valid_before, @@ -1390,8 +1381,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux #[cfg(all(unix, feature = "rsa"))] async fn test_sign_request_cert_rsa() { use crate::keys::agent::client::AgentClient; - use ssh_key::rand_core::OsRng; - use std::io::Write; + use std::io::Write; use std::process::Stdio; env_logger::try_init().unwrap_or(()); @@ -1400,14 +1390,14 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux // Create RSA CA key and user key let ca_key = PrivateKey::random( - &mut OsRng, + &mut rand::rng(), ssh_key::Algorithm::Rsa { hash: Some(HashAlg::Sha256), }, ) .unwrap(); let user_key = PrivateKey::random( - &mut OsRng, + &mut rand::rng(), ssh_key::Algorithm::Rsa { hash: Some(HashAlg::Sha256), }, @@ -1485,8 +1475,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux #[cfg(all(unix, feature = "rsa"))] async fn test_sign_request_cert_rsa_sha512() { use crate::keys::agent::client::AgentClient; - use ssh_key::rand_core::OsRng; - use std::io::Write; + use std::io::Write; use std::process::Stdio; env_logger::try_init().unwrap_or(()); @@ -1495,14 +1484,14 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux // Create RSA CA key and user key let ca_key = PrivateKey::random( - &mut OsRng, + &mut rand::rng(), ssh_key::Algorithm::Rsa { hash: Some(HashAlg::Sha512), }, ) .unwrap(); let user_key = PrivateKey::random( - &mut OsRng, + &mut rand::rng(), ssh_key::Algorithm::Rsa { hash: Some(HashAlg::Sha512), }, diff --git a/crates/bssh-russh/src/negotiation.rs b/crates/bssh-russh/src/negotiation.rs index 2b5b0c7f..6ef741ff 100644 --- a/crates/bssh-russh/src/negotiation.rs +++ b/crates/bssh-russh/src/negotiation.rs @@ -15,7 +15,7 @@ use std::borrow::Cow; use log::debug; -use rand::RngCore; +use rand_core::Rng; use ssh_encoding::{Decode, Encode}; use ssh_key::{Algorithm, EcdsaCurve, HashAlg, PrivateKey}; diff --git a/crates/bssh-russh/src/sshbuffer.rs b/crates/bssh-russh/src/sshbuffer.rs index d7d72940..cf995891 100644 --- a/crates/bssh-russh/src/sshbuffer.rs +++ b/crates/bssh-russh/src/sshbuffer.rs @@ -17,7 +17,7 @@ use core::fmt; use std::borrow::Cow; use std::num::Wrapping; -use cipher::SealingKey; +use super::cipher::SealingKey; use compression::Compress; use tokio::io::{AsyncWrite, AsyncWriteExt}; diff --git a/crates/bssh-russh/src/tests.rs b/crates/bssh-russh/src/tests.rs index fe6430bc..232ac9fa 100644 --- a/crates/bssh-russh/src/tests.rs +++ b/crates/bssh-russh/src/tests.rs @@ -8,7 +8,6 @@ mod compress { use std::collections::HashMap; use std::sync::{Arc, Mutex}; - use crate::keys::ssh_key::rand_core::OsRng; use keys::PrivateKeyWithHashAlg; use log::debug; use ssh_key::PrivateKey; @@ -21,14 +20,14 @@ mod compress { async fn compress_local_test() { let _ = env_logger::try_init(); - let client_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let client_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); let mut config = server::Config::default(); config.preferred = Preferred::COMPRESSED; config.inactivity_timeout = None; // Some(std::time::Duration::from_secs(3)); config.auth_rejection_time = std::time::Duration::from_secs(3); config .keys - .push(PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap()); + .push(PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap()); let config = Arc::new(config); let mut sh = Server { clients: Arc::new(Mutex::new(HashMap::new())), @@ -139,7 +138,6 @@ mod compress { } mod channels { - use elliptic_curve::rand_core::OsRng; use keys::PrivateKeyWithHashAlg; use server::Session; use ssh_key::PrivateKey; @@ -166,13 +164,13 @@ mod channels { let _ = env_logger::try_init(); - let client_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let client_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); let mut config = server::Config::default(); config.inactivity_timeout = None; config.auth_rejection_time = std::time::Duration::from_secs(3); config .keys - .push(PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap()); + .push(PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap()); let config = Arc::new(config); let socket = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap(); let addr = socket.local_addr().unwrap(); @@ -643,6 +641,26 @@ mod channels { } } +mod gex { + use super::*; + + #[test] + fn peer_request_accepts_rfc4419_minimum_when_server_can_choose_stronger_group() { + let params = client::GexParams::from_peer_request(1024, 4097, 8192).unwrap(); + + assert_eq!(params.min_group_size(), 1024); + assert_eq!(params.preferred_group_size(), 4097); + assert_eq!(params.max_group_size(), 8192); + } + + #[test] + fn local_client_config_still_rejects_minimum_below_2048() { + let error = client::GexParams::for_client_config(1024, 4097, 8192).unwrap_err(); + + assert!(matches!(error, Error::InvalidConfig(_))); + } +} + mod server_kex_junk { use std::sync::Arc; @@ -704,7 +722,6 @@ mod future_certificate { use std::sync::Arc; use ssh_key::{certificate, PrivateKey}; - use ssh_key::rand_core::OsRng; use crate::keys::agent::client::AgentClient; use crate::{client, server}; @@ -747,7 +764,7 @@ mod future_certificate { let valid_before = now + 86400 * 365; let mut builder = certificate::Builder::new_with_random_nonce( - &mut OsRng, + &mut rand::rng(), user_key.public_key(), valid_after, valid_before, @@ -769,8 +786,8 @@ mod future_certificate { let (mut agent, agent_path, dir) = spawn_agent().await; // 2. Create CA key and user key - let ca_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); - let user_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(); + let ca_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); + let user_key = PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap(); // 3. Create a certificate let cert = create_test_cert(&ca_key, &user_key); @@ -812,7 +829,7 @@ mod future_certificate { server_config.auth_rejection_time = std::time::Duration::from_secs(3); server_config .keys - .push(PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap()); + .push(PrivateKey::random(&mut rand::rng(), ssh_key::Algorithm::Ed25519).unwrap()); let server_config = Arc::new(server_config); let socket = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap(); diff --git a/src/bin/bssh_server.rs b/src/bin/bssh_server.rs index 4d0a6738..98776219 100644 --- a/src/bin/bssh_server.rs +++ b/src/bin/bssh_server.rs @@ -359,13 +359,12 @@ fn check_config(cli: &Cli) -> Result<()> { /// Generate SSH host keys fn gen_host_key(key_type: &str, output: &PathBuf, _bits: u32) -> Result<()> { use russh::keys::PrivateKey; - use ssh_key::rand_core::OsRng; use ssh_key::LineEnding; let key = match key_type.to_lowercase().as_str() { "ed25519" => { tracing::info!("Generating Ed25519 host key"); - PrivateKey::random(&mut OsRng, russh::keys::Algorithm::Ed25519) + PrivateKey::random(&mut rand::rng(), russh::keys::Algorithm::Ed25519) .context("Failed to generate Ed25519 key")? } "rsa" => { @@ -374,7 +373,7 @@ fn gen_host_key(key_type: &str, output: &PathBuf, _bits: u32) -> Result<()> { } tracing::info!(bits = _bits, "Generating RSA host key"); PrivateKey::random( - &mut OsRng, + &mut rand::rng(), russh::keys::Algorithm::Rsa { hash: Some(russh::keys::HashAlg::Sha256), }, diff --git a/src/keygen/ed25519.rs b/src/keygen/ed25519.rs index d3bf7f79..93bc063a 100644 --- a/src/keygen/ed25519.rs +++ b/src/keygen/ed25519.rs @@ -24,7 +24,6 @@ use super::GeneratedKey; use anyhow::{Context, Result}; use russh::keys::{Algorithm, HashAlg, PrivateKey}; -use ssh_key::rand_core::OsRng; use ssh_key::LineEnding; use std::io::Write; use std::path::Path; @@ -43,7 +42,7 @@ pub fn generate(output_path: &Path, comment: Option<&str>) -> Result) -> Result< // Generate key pair using cryptographically secure RNG // Use SHA-256 for the RSA signature hash algorithm let keypair = PrivateKey::random( - &mut OsRng, + &mut rand::rng(), Algorithm::Rsa { hash: Some(HashAlg::Sha256), },