diff --git a/Cargo.lock b/Cargo.lock index f42bd2d..2074240 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,19 @@ version = 4 [[package]] name = "aead" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5f451b77e2f92932dc411da6ef9f3d33efad68a6f14a7a83e559453458e85ac" +checksum = "c01559752fbde7734af628961723aa734aa46351cbf5c9ce41133ad2ae1a09b9" dependencies = [ "crypto-common", + "inout", ] [[package]] name = "aes" -version = "0.9.0-pre.1" +version = "0.9.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183b3b4639f8f7237857117abb74f3dc8648b77e67ff78d9cb6959fd7e76f387" +checksum = "cd4838e4ad37bb032dea137f441d5f71c16c26c068af512e64c5bc13a88cdfc7" dependencies = [ "cfg-if", "cipher", @@ -25,9 +26,9 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.11.0-pre.1" +version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ca4317859cecdb9849cf94087998a04efc7beedc07855836cb2534fd9aa4db" +checksum = "2be322be4a73a3a55ad74b9833238e76bfd6034ce69a05c1b41c879f6a3bdca6" dependencies = [ "aead", "aes", @@ -40,9 +41,9 @@ dependencies = [ [[package]] name = "argon2" -version = "0.6.0-pre.1" +version = "0.6.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f95281c5706985b6c00f8a2270438f968d475672aa68a4a85cddcb57a68577b" +checksum = "99d62242539f39ae10c6654d86121e152344e24329c4adb921d672b6369f47a2" dependencies = [ "base64ct", "blake2", @@ -70,47 +71,53 @@ checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bcrypt-pbkdf" -version = "0.11.0-pre.1" +version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995d049b2af860ac443b0d730729a8fc3624fbe731db8a6285f270f3c4040587" +checksum = "3cc110942d74f151c8944335316ae8d07cfbc4e0282e883c5d20e3ca284b40b0" dependencies = [ "blowfish", "pbkdf2", "sha2", ] +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + [[package]] name = "blake2" -version = "0.11.0-pre.4" +version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6dbf347378982186052c47f25f33fc1a6eb439ee840d778eb3ec132e304379d" +checksum = "ce3d950855224a23299348898f8a2127860e1afea78df3e51deebb89d1cb2f8f" dependencies = [ "digest", ] [[package]] name = "block-buffer" -version = "0.11.0-rc.0" +version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17092d478f4fadfb35a7e082f62e49f0907fdf048801d9d706277e34f9df8a78" +checksum = "a229bfd78e4827c91b9b95784f69492c1b77c1ab75a45a8a037b139215086f94" dependencies = [ - "crypto-common", + "hybrid-array", ] [[package]] name = "block-padding" -version = "0.4.0-rc.0" +version = "0.4.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d7992d59cd95a984bde8833d4d025886eec3718777971ad15c58df0b070254a" +checksum = "ee88d14c41bbae2e333f574a27fc73d96fe1039e5a356c20d06a7f2a34cd8e5a" dependencies = [ "hybrid-array", ] [[package]] name = "blowfish" -version = "0.10.0-pre.1" +version = "0.10.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f27c154f70281cf2775de16a3380c477f9c2c89ec1f122786b5afa7add0c8a3" +checksum = "3c0f960d119fb9f71bf044c0f2f91bf6323d749e7302f3ef110a34cd73a5a0d2" dependencies = [ "byteorder", "cipher", @@ -130,9 +137,9 @@ checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cbc" -version = "0.2.0-pre.1" +version = "0.2.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f400d6c533c8e3b0545892ac95831d897c816335fec5d2d57d886a241acf13e" +checksum = "3ef95f543a56c245d9d0826ccbb34636ee983b3e846eff57bc5fc72e1bce1701" dependencies = [ "cipher", ] @@ -145,9 +152,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chacha20" -version = "0.10.0-pre.1" +version = "0.10.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6a99ac5abed8864eaedd3b95efdab3e10f41f008f0967bb9c53b093eeb3c62" +checksum = "6e057d7ab0331b90074df7ca698b3361860c20a1d8c8e28f49c01f526e3f3958" dependencies = [ "cfg-if", "cipher", @@ -157,9 +164,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre.6" +version = "0.5.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71c893d5a1e8257048dbb29954d2e1f85f091a150304f1defe4ca2806da5d3f" +checksum = "bd4ef774202f1749465fc7cf88d70fc30620e8cacd5429268f4bff7d003bd976" dependencies = [ "crypto-common", "inout", @@ -168,48 +175,58 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.10.0-rc.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9adcf94f05e094fca3005698822ec791cb4433ced416afda1c5ca3b8dfc05a2f" +checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crypto-bigint" -version = "0.6.0-rc.2" +version = "0.7.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43027691f1c055da3da4f7d96af09fcec420d435d5616e51f29afd0811c56a7" +checksum = "edaae5fb9dac79a07260e0b2006799ff4f1d342ab243fd7d0892215113b27904" dependencies = [ "hybrid-array", "num-traits", "rand_core", + "serdect", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.2.0-rc.0" +version = "0.2.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b" +checksum = "8a23fa214dea9efd4dacee5a5614646b30216ae0f05d4bb51bafb50e9da1c5be" dependencies = [ - "getrandom", "hybrid-array", +] + +[[package]] +name = "crypto-primes" +version = "0.7.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae744b9f528151f8c440cf67498f24d2d1ac0ab536b5ce7b1f87a7a5961bd1c1" +dependencies = [ + "crypto-bigint", + "libm", "rand_core", ] [[package]] name = "ctr" -version = "0.10.0-pre.1" +version = "0.10.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1637b299862a663dd5af70ee109d53555eff68b99b454fe535ed6599b0e9b3" +checksum = "f239edce204df0e4503cccef3492552773d1ca4e002659a59ca715f099b45ca1" dependencies = [ "cipher", ] @@ -217,7 +234,7 @@ dependencies = [ [[package]] name = "curve25519-dalek" version = "4.1.3" -source = "git+https://github.com/dalek-cryptography/curve25519-dalek.git?branch=rustcrypto-new-releases#44508ba8652ae3445608ad3c56b63ef528ddfb93" +source = "git+https://github.com/dalek-cryptography/curve25519-dalek.git?branch=rustcrypto-new-releases#88e1efaae36d4438fd3f17ad3cb043dd3da844d4" dependencies = [ "cfg-if", "cpufeatures", @@ -231,7 +248,7 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" version = "0.1.1" -source = "git+https://github.com/dalek-cryptography/curve25519-dalek.git?branch=rustcrypto-new-releases#44508ba8652ae3445608ad3c56b63ef528ddfb93" +source = "git+https://github.com/dalek-cryptography/curve25519-dalek.git?branch=rustcrypto-new-releases#88e1efaae36d4438fd3f17ad3cb043dd3da844d4" dependencies = [ "proc-macro2", "quote", @@ -240,9 +257,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.0" +version = "0.8.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" +checksum = "b00a9651bf9c00a38b7c383073cb22fb42f20a5f978c9f97ad5c7128cbd3c1bd" dependencies = [ "const-oid", "zeroize", @@ -250,18 +267,18 @@ dependencies = [ [[package]] name = "des" -version = "0.9.0-pre.1" +version = "0.9.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291fd90b2979cd5898c7065de0ceef1b7b9c477fe9b3389e995fa8c2cef7cc56" +checksum = "8025983b9f9f242e94d459a57b81c571e92e4e1717ca57d092d8a69fc539efa1" dependencies = [ "cipher", ] [[package]] name = "digest" -version = "0.11.0-pre.9" +version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" +checksum = "460dd7f37e4950526b54a5a6b1f41b6c8e763c58eb9a8fc8fc05ba5c2f44ca7b" dependencies = [ "block-buffer", "const-oid", @@ -271,13 +288,13 @@ dependencies = [ [[package]] name = "dsa" -version = "0.7.0-pre.1" +version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e0b1a3c7540d48f58eca5ddfdeb40a44aff3047bf15fe4fb6162a673ddd5fa" +checksum = "f7db0cefc575aba0011f77f56b733d6674b926f64211dca9d7254d47d5c425bb" dependencies = [ + "crypto-bigint", + "crypto-primes", "digest", - "num-bigint-dig", - "num-traits", "pkcs8", "rfc6979", "sha2", @@ -287,9 +304,9 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.17.0-pre.7" +version = "0.17.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad051af2b2d2f356d716138c76775929be913deb5b4ea217cd2613535936bef" +checksum = "abbc927a7e946a78fbff19c283bc5d4f8960d9000049a7e2b0d84cb2730613c4" dependencies = [ "der", "digest", @@ -297,13 +314,14 @@ dependencies = [ "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.3.0-pre.0" +version = "3.0.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bcc0730fbd27c8619332efad3dfa1de229dc5859a31495ab674e0ac0f9996b" +checksum = "e6e01f644da45b2f83a7c40f6895ccc467ce60d6163c729d9fe4351eaa42c512" dependencies = [ "signature", ] @@ -311,7 +329,7 @@ dependencies = [ [[package]] name = "ed25519-dalek" version = "2.2.0-pre" -source = "git+https://github.com/dalek-cryptography/curve25519-dalek.git?branch=rustcrypto-new-releases#44508ba8652ae3445608ad3c56b63ef528ddfb93" +source = "git+https://github.com/dalek-cryptography/curve25519-dalek.git?branch=rustcrypto-new-releases#88e1efaae36d4438fd3f17ad3cb043dd3da844d4" dependencies = [ "curve25519-dalek", "ed25519", @@ -321,9 +339,9 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-pre.6" +version = "0.14.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ed8e96bb573517f42470775f8ef1b9cd7595de52ba7a8e19c48325a92c8fe4f" +checksum = "bedd367b8649edac0efb2120e420460cffc41988f94eb55f009832484a45c46f" dependencies = [ "base16ct", "crypto-bigint", @@ -340,9 +358,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.13.0" +version = "0.14.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "d42dd26f5790eda47c1a2158ea4120e32c35ddc9a7743c98a292accc01b54ef3" dependencies = [ "rand_core", "subtle", @@ -356,30 +374,30 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "getrandom" -version = "0.2.15" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", + "r-efi", "wasi", ] [[package]] name = "ghash" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b92860fda25ab571512af210134cde2c42732cd53253bcee3f21b288b7afbc4" +checksum = "7df2ef47489983b86b012ce4955b61fcfb1a99a761a1a8c79c3129e722da6795" dependencies = [ - "opaque-debug", "polyval", ] [[package]] name = "group" -version = "0.13.0" +version = "0.14.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "1ff6a0b2dd4b981b1ae9e3e6830ab146771f3660d31d57bafd9018805a91b0f1" dependencies = [ "ff", "rand_core", @@ -400,9 +418,9 @@ checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" [[package]] name = "hmac" -version = "0.13.0-pre.4" +version = "0.13.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b1fb14e4df79f9406b434b60acef9f45c26c50062cccf1346c6103b8c47d58" +checksum = "8dc6a2fcc35ab09136c6df2cdf9ca49790701420a3a6b5db0987dddbabc79b21" dependencies = [ "digest", ] @@ -418,9 +436,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.11" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5a41e5b0754cae5aaf7915f1df1147ba8d316fc6e019cfcc00fbaba96d5e030" +checksum = "891d15931895091dea5c47afa5b3c9a01ba634b311919fd4d41388fa0e3d76af" dependencies = [ "typenum", "zeroize", @@ -428,23 +446,14 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-rc.0" +version = "0.2.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc33218cf9ce7b927426ee4ad3501bcc5d8c26bf5fb4a82849a083715aca427" +checksum = "c774c86bce20ea04abe1c37cf0051c5690079a3a28ef5fdac2a5a0412b3d7d74" dependencies = [ "block-padding", "hybrid-array", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - [[package]] name = "libc" version = "0.2.155" @@ -453,46 +462,9 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "num-bigint-dig" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" -dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand", - "smallvec", - "zeroize", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "num-traits" @@ -501,44 +473,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "p256" -version = "0.14.0-pre.1" +version = "0.14.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c32c18a74d9dda1314d2f945fb3e274848822f63f264a9e4d3f783e29b3bc1f" +checksum = "635e1f1e5af6fc13e6c6a587fa1455e17fa7c8b54ba74093be5254819e34713f" dependencies = [ "ecdsa", "elliptic-curve", + "primefield", "primeorder", "sha2", ] [[package]] name = "p384" -version = "0.14.0-pre.1" +version = "0.14.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99acc40dbfad9cc3dc102828f5678c8ca14f0cbf3a1f56f74c2875b5a84427af" +checksum = "e029b66d7fbea49e7b510de607a2cacdbb2fc79d67856689d223ad8aa7fa91e3" dependencies = [ "ecdsa", "elliptic-curve", + "primefield", "primeorder", "sha2", ] [[package]] name = "p521" -version = "0.14.0-pre.1" +version = "0.14.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec5d919bea930a34a522bb1c95a89f559925deab255db2c2ffa174fc48df664" +checksum = "cd3a148e2ddfbf70d45fb1350f8bafb399d20c0a3f381ba1fbb5c680ccfe4d37" dependencies = [ "base16ct", "ecdsa", @@ -550,9 +517,9 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3b470a56963403c40f9dbb41eaee539759de9d026d3324da705a0ae0d269cd" +checksum = "8ee14c44aa1c04c22c4d4532c4fa2cdd5b6d31c2514a5898530d889fc2fc2737" dependencies = [ "base64ct", "rand_core", @@ -561,27 +528,27 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.13.0-pre.1" +version = "0.13.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e11753d5193f26dc27ae698e0b536b5e511b7799c5ac475ec10783f26d164a" +checksum = "c2efb182a4d7d26aa7442a4ef2f91c5021c6abb61f9fdd251fcc2e327f5faaf6" dependencies = [ "digest", ] [[package]] name = "pem-rfc7468" -version = "1.0.0-rc.2" +version = "1.0.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dfbfa5c6f0906884269722c5478e72fd4d6c0e24fe600332c6d62359567ce1" +checksum = "a8e58fab693c712c0d4e88f8eb3087b6521d060bcaf76aeb20cb192d809115ba" dependencies = [ "base64ct", ] [[package]] name = "pkcs1" -version = "0.8.0-rc.1" +version = "0.8.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226eb25e2c46c166ce498ac0f606ac623142d640064879ff445938accddff1e2" +checksum = "24e16d93c725fa250577ffdec06ebbff4cae3625b0e2881ac43a5427797ee8d3" dependencies = [ "der", "pkcs8", @@ -590,9 +557,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-rc.1" +version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eacd2c7141f32aef1cfd1ad0defb5287a3d94592d7ab57c1ae20e3f9f1f0db1f" +checksum = "3f1843d4345dfe1a55e487db747a04c01af50415b03e937410e0a41d8cc24ec7" dependencies = [ "der", "spki", @@ -600,25 +567,23 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.9.0-rc.0" +version = "0.9.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72844372b6c796d771899186be2c255818fdc21c68d6e2be2c7ffa509ade9df4" +checksum = "acc2072a7f2eb76d8cb988195d48046451ea2c3dc98a5bbe1b112b70e1cffa60" dependencies = [ "cpufeatures", - "opaque-debug", "universal-hash", "zeroize", ] [[package]] name = "polyval" -version = "0.7.0-rc.0" +version = "0.7.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01cbf5c028f9f862c6f7f5a5544307d7858634df190488d432ec470c8fbc063" +checksum = "ff52e661730d7c6f95a72137e812e337eb5ff371d38d8588798e0df8404e610c" dependencies = [ "cfg-if", "cpufeatures", - "opaque-debug", "universal-hash", ] @@ -630,15 +595,22 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "primefield" -version = "0.14.0-pre.0" +version = "0.14.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f2ce0fa9cccdaf216230d151ce51a15298aef50ad76081a830128ecbc6428a" +checksum = "1bbeb92947a0d0d4b0cab5e2e6749acc44c81461eb3b1aff4dbb7acd0eb9f0ab" +dependencies = [ + "crypto-bigint", + "ff", + "rand_core", + "subtle", + "zeroize", +] [[package]] name = "primeorder" -version = "0.14.0-pre.1" +version = "0.14.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bed0c431186675ad845922b903d28c7faa2b634a6d130fb7b50bb289f5a4d52" +checksum = "f2e45e9e037423d1d08cad23132bef43fda87481e362154fd145831028dcf3b8" dependencies = [ "elliptic-curve", ] @@ -662,20 +634,16 @@ dependencies = [ ] [[package]] -name = "rand" -version = "0.8.5" +name = "r-efi" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "rand_chacha", - "rand_core", -] +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] name = "rand_chacha" -version = "0.3.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", @@ -683,18 +651,18 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom", ] [[package]] name = "rfc6979" -version = "0.5.0-pre.4" +version = "0.5.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871ee76a3eee98b0f805e5d1caf26929f4565073c580c053a55f886fc15dea49" +checksum = "f53f124bf3ec90be84ae97d7f52175ba938898525554c13c9017eb8f0a604146" dependencies = [ "hmac", "subtle", @@ -702,15 +670,14 @@ dependencies = [ [[package]] name = "rsa" -version = "0.10.0-pre.3" +version = "0.10.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07058e83b684989ab0559f9e22322f4e3f7e49147834ed0bae40486b9e70473c" +checksum = "f30f0ad781aea19fe741d7a901b2ad8b4271ac3516e7045b8ecff74e201968fe" dependencies = [ "const-oid", + "crypto-bigint", + "crypto-primes", "digest", - "num-bigint-dig", - "num-integer", - "num-traits", "pkcs1", "pkcs8", "rand_core", @@ -732,9 +699,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.8.0-rc.3" +version = "0.8.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1988446eff153796413a73669dfaa4caa3f5ce8b25fac89e3821a39c611772e" +checksum = "e4855dd9b15e8e469fad23529698f7f7b7a6b250a81c88b1f9d7efe1abca7717" dependencies = [ "base16ct", "der", @@ -770,11 +737,21 @@ dependencies = [ "syn", ] +[[package]] +name = "serdect" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha1" -version = "0.11.0-pre.4" +version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9540978cef7a8498211c1b1c14e5ce920fe5bd524ea84f4a3d72d4602515ae93" +checksum = "6f9318facddf9ac32a33527066936837e189b3f23ced6edc1603720ead5e2b3d" dependencies = [ "cfg-if", "cpufeatures", @@ -783,9 +760,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0-pre.4" +version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5" +checksum = "aa1d2e6b3cc4e43a8258a9a3b17aa5dfd2cc5186c7024bba8a64aa65b2c71a59" dependencies = [ "cfg-if", "cpufeatures", @@ -794,31 +771,19 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.4" +version = "3.0.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054d71959c7051b9042c26af337f05cc930575ed2604d7d3ced3158383e59734" +checksum = "d7ae074ff622614874804868b07d9cb786223082c9fe726a6653608f32f37b02" dependencies = [ "digest", "rand_core", ] -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "spki" -version = "0.8.0-rc.0" +version = "0.8.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3fb1c675852398475928637b3ebbdd7e1d0cc24d27b3bbc81788b4eb51e310" +checksum = "c2f0e2bdca9b00f5be6dd3bb6647d50fd0f24a508a95f78e3bb2fe98d0403c85" dependencies = [ "base64ct", "der", @@ -858,9 +823,9 @@ version = "0.3.0-pre.1" dependencies = [ "base64ct", "bytes", + "crypto-bigint", "digest", "hex-literal", - "num-bigint-dig", "pem-rfc7468", "ssh-derive", "subtle", @@ -879,7 +844,6 @@ dependencies = [ "hex-literal", "hmac", "home", - "num-bigint-dig", "p256", "p384", "p521", @@ -937,9 +901,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "universal-hash" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3517d72c5ca6d60f9f2e85d2c772e2652830062a685105a528d19dd823cf87d5" +checksum = "17866ce72039aaa929b785c51d08d0395e02cb5eaffd3efdf634b9b1f80b8157" dependencies = [ "crypto-common", "subtle", @@ -947,9 +911,12 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] [[package]] name = "windows-sys" @@ -1024,6 +991,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + [[package]] name = "zeroize" version = "1.8.1" diff --git a/ssh-cipher/Cargo.toml b/ssh-cipher/Cargo.toml index 75635c2..191c340 100644 --- a/ssh-cipher/Cargo.toml +++ b/ssh-cipher/Cargo.toml @@ -19,18 +19,18 @@ edition = "2024" rust-version = "1.85" [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "0.5.0-rc.0" encoding = { package = "ssh-encoding", version = "=0.3.0-pre.1", path = "../ssh-encoding" } # optional dependencies -aead = { version = "0.6.0-rc.0", optional = true, default-features = false } -aes = { version = "=0.9.0-pre.1", optional = true, default-features = false } -aes-gcm = { version = "=0.11.0-pre.1", optional = true, default-features = false, features = ["aes"] } -cbc = { version = "=0.2.0-pre.1", optional = true } -ctr = { version = "=0.10.0-pre.1", optional = true, default-features = false } -chacha20 = { version = "=0.10.0-pre.1", optional = true, default-features = false, features = ["cipher", "legacy"] } -des = { version = "=0.9.0-pre.1", optional = true, default-features = false } -poly1305 = { version = "0.9.0-rc.0", optional = true, default-features = false } +aead = { version = "0.6.0-rc.1", optional = true, default-features = false } +aes = { version = "0.9.0-rc.0", optional = true, default-features = false } +aes-gcm = { version = "0.11.0-rc.0", optional = true, default-features = false, features = ["aes"] } +cbc = { version = "0.2.0-rc.0", optional = true } +ctr = { version = "0.10.0-rc.0", optional = true, default-features = false } +chacha20 = { version = "0.10.0-rc.0", optional = true, default-features = false, features = ["cipher", "legacy"] } +des = { version = "0.9.0-rc.0", optional = true, default-features = false } +poly1305 = { version = "0.9.0-rc.1", optional = true, default-features = false } subtle = { version = "2", optional = true, default-features = false } zeroize = { version = "1", optional = true, default-features = false } diff --git a/ssh-cipher/src/chacha20poly1305.rs b/ssh-cipher/src/chacha20poly1305.rs index 89d0eac..ef14cda 100644 --- a/ssh-cipher/src/chacha20poly1305.rs +++ b/ssh-cipher/src/chacha20poly1305.rs @@ -4,8 +4,8 @@ pub use chacha20::ChaCha20Legacy as ChaCha20; use crate::Tag; use aead::{ - AeadCore, Error, KeyInit, KeySizeUser, Result, - array::typenum::{U0, U8, U16, U32}, + AeadCore, Error, KeyInit, KeySizeUser, Result, TagPosition, + array::typenum::{U8, U16, U32}, }; use cipher::{KeyIvInit, StreamCipher, StreamCipherSeek}; use poly1305::Poly1305; @@ -49,7 +49,7 @@ impl KeyInit for ChaCha20Poly1305 { impl AeadCore for ChaCha20Poly1305 { type NonceSize = U8; type TagSize = U16; - type CiphertextOverhead = U0; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } impl ChaCha20Poly1305 { diff --git a/ssh-cipher/src/decryptor.rs b/ssh-cipher/src/decryptor.rs index e7b4810..d1ecca7 100644 --- a/ssh-cipher/src/decryptor.rs +++ b/ssh-cipher/src/decryptor.rs @@ -13,7 +13,10 @@ use des::TdesEde3; use aes::{Aes128, Aes192, Aes256}; #[cfg(any(feature = "aes-cbc", feature = "tdes"))] -use cipher::{Block, BlockCipher, BlockCipherDecrypt, BlockModeDecrypt}; +use cipher::{ + Block, + block::{BlockCipherDecrypt, BlockModeDecrypt}, +}; /// Stateful decryptor object for unauthenticated SSH symmetric ciphers. /// @@ -137,7 +140,7 @@ impl Decryptor { #[cfg(any(feature = "aes-cbc", feature = "tdes"))] fn cbc_decrypt(decryptor: &mut cbc::Decryptor, buffer: &mut [u8]) -> Result<()> where - C: BlockCipher + BlockCipherDecrypt, + C: BlockCipherDecrypt, { let (blocks, remaining) = Block::::slice_as_chunks_mut(buffer); diff --git a/ssh-cipher/src/encryptor.rs b/ssh-cipher/src/encryptor.rs index 67c9a2a..7082e27 100644 --- a/ssh-cipher/src/encryptor.rs +++ b/ssh-cipher/src/encryptor.rs @@ -1,12 +1,12 @@ //! Stateful encryptor object. use crate::{Cipher, Error, Result}; -use cipher::{Block, BlockCipher, BlockCipherEncrypt, KeyIvInit}; +use cipher::{Block, BlockCipherEncrypt, KeyIvInit}; #[cfg(feature = "aes-ctr")] use { crate::Ctr128BE, - cipher::{StreamCipherCore, array::sizes::U16}, + cipher::{BlockSizeUser, StreamCipherCore, array::sizes::U16}, }; #[cfg(feature = "tdes")] @@ -16,7 +16,7 @@ use des::TdesEde3; use aes::{Aes128, Aes192, Aes256}; #[cfg(any(feature = "aes-cbc", feature = "tdes"))] -use cipher::BlockModeEncrypt; +use cipher::block::BlockModeEncrypt; /// Stateful encryptor object for unauthenticated SSH symmetric ciphers. /// @@ -122,7 +122,7 @@ impl Encryptor { #[cfg(any(feature = "aes-cbc", feature = "tdes"))] fn cbc_encrypt(encryptor: &mut cbc::Encryptor, buffer: &mut [u8]) -> Result<()> where - C: BlockCipher + BlockCipherEncrypt, + C: BlockCipherEncrypt, { let (blocks, remaining) = Block::::slice_as_chunks_mut(buffer); @@ -139,7 +139,7 @@ where #[cfg(feature = "aes-ctr")] pub(crate) fn ctr_encrypt(encryptor: &mut Ctr128BE, buffer: &mut [u8]) -> Result<()> where - C: BlockCipher + BlockCipherEncrypt, + C: BlockCipherEncrypt + BlockSizeUser, { let (blocks, remaining) = Block::::slice_as_chunks_mut(buffer); diff --git a/ssh-cipher/src/lib.rs b/ssh-cipher/src/lib.rs index 9412ddf..f015df7 100644 --- a/ssh-cipher/src/lib.rs +++ b/ssh-cipher/src/lib.rs @@ -45,7 +45,7 @@ use encoding::{Label, LabelError}; #[cfg(feature = "aes-gcm")] use { - aead::{AeadInPlace, array::typenum::U12}, + aead::{AeadInOut, array::typenum::U12}, aes_gcm::{Aes128Gcm, Aes256Gcm}, }; @@ -236,7 +236,7 @@ impl Cipher { let nonce = iv.try_into().map_err(|_| Error::IvSize)?; let tag = tag.ok_or(Error::TagSize)?; cipher - .decrypt_in_place_detached(nonce, &[], buffer, &tag) + .decrypt_inout_detached(nonce, &[], buffer.into(), &tag) .map_err(|_| Error::Crypto)?; Ok(()) @@ -247,7 +247,7 @@ impl Cipher { let nonce = iv.try_into().map_err(|_| Error::IvSize)?; let tag = tag.ok_or(Error::TagSize)?; cipher - .decrypt_in_place_detached(nonce, &[], buffer, &tag) + .decrypt_inout_detached(nonce, &[], buffer.into(), &tag) .map_err(|_| Error::Crypto)?; Ok(()) @@ -300,7 +300,7 @@ impl Cipher { let cipher = Aes128Gcm::new_from_slice(key).map_err(|_| Error::KeySize)?; let nonce = iv.try_into().map_err(|_| Error::IvSize)?; let tag = cipher - .encrypt_in_place_detached(nonce, &[], buffer) + .encrypt_inout_detached(nonce, &[], buffer.into()) .map_err(|_| Error::Crypto)?; Ok(Some(tag)) @@ -310,7 +310,7 @@ impl Cipher { let cipher = Aes256Gcm::new_from_slice(key).map_err(|_| Error::KeySize)?; let nonce = iv.try_into().map_err(|_| Error::IvSize)?; let tag = cipher - .encrypt_in_place_detached(nonce, &[], buffer) + .encrypt_inout_detached(nonce, &[], buffer.into()) .map_err(|_| Error::Crypto)?; Ok(Some(tag)) diff --git a/ssh-encoding/Cargo.toml b/ssh-encoding/Cargo.toml index c8bbc37..5787e75 100644 --- a/ssh-encoding/Cargo.toml +++ b/ssh-encoding/Cargo.toml @@ -17,16 +17,14 @@ rust-version = "1.85" [dependencies] base64ct = { version = "1.7", optional = true } +bigint = { package = "crypto-bigint", version = "=0.7.0-pre.4", optional = true, default-features = false, features = ["alloc"] } bytes = { version = "1", optional = true, default-features = false } -digest = { version = "=0.11.0-pre.9", optional = true, default-features = false } -pem-rfc7468 = { version = "1.0.0-rc.2", optional = true } +digest = { version = "0.11.0-rc.0", optional = true, default-features = false } +pem-rfc7468 = { version = "1.0.0-rc.3", optional = true } ssh-derive = { version = "0.0.1-alpha", optional = true, path = "../ssh-derive" } subtle = { version = "2", optional = true, default-features = false } zeroize = { version = "1", optional = true, default-features = false } -# TODO(tarcieri): migrate to `crypto-bigint` -bigint = { package = "num-bigint-dig", version = "0.8", optional = true, default-features = false } - [dev-dependencies] hex-literal = "1" diff --git a/ssh-encoding/src/error.rs b/ssh-encoding/src/error.rs index b2a967e..6e3c110 100644 --- a/ssh-encoding/src/error.rs +++ b/ssh-encoding/src/error.rs @@ -119,6 +119,13 @@ impl From for Error { } } +#[cfg(feature = "bigint")] +impl From for Error { + fn from(_: bigint::DecodeError) -> Error { + Error::MpintEncoding + } +} + #[cfg(feature = "pem")] impl From for Error { fn from(err: pem_rfc7468::Error) -> Error { diff --git a/ssh-encoding/src/lib.rs b/ssh-encoding/src/lib.rs index a256466..23f0637 100644 --- a/ssh-encoding/src/lib.rs +++ b/ssh-encoding/src/lib.rs @@ -242,6 +242,9 @@ pub use crate::mpint::Mpint; #[cfg(feature = "base64")] pub use crate::{base64::Base64Reader, base64::Base64Writer}; +#[cfg(feature = "bigint")] +pub use bigint; + #[cfg(feature = "bytes")] pub use bytes; @@ -258,3 +261,14 @@ pub use ssh_derive::{Decode, Encode}; #[cfg(all(doc, feature = "alloc"))] use alloc::vec::Vec; + +#[cfg(feature = "bigint")] +pub use bigint::BoxedUint as Uint; + +/// Non-zero [`Uint`]. +#[cfg(feature = "bigint")] +pub type NonZeroUint = bigint::NonZero; + +/// Odd [`Uint`]. +#[cfg(feature = "bigint")] +pub type OddUint = bigint::Odd; diff --git a/ssh-encoding/src/mpint.rs b/ssh-encoding/src/mpint.rs index 3b971eb..6aeeebc 100644 --- a/ssh-encoding/src/mpint.rs +++ b/ssh-encoding/src/mpint.rs @@ -4,6 +4,9 @@ use crate::{CheckedSum, Decode, Encode, Error, Reader, Result, Writer}; use alloc::{boxed::Box, vec::Vec}; use core::fmt; +#[cfg(feature = "bigint")] +use crate::{NonZeroUint, OddUint, Uint}; + #[cfg(feature = "subtle")] use subtle::{Choice, ConstantTimeEq}; @@ -205,45 +208,125 @@ impl fmt::UpperHex for Mpint { } #[cfg(feature = "bigint")] -impl TryFrom for Mpint { +impl TryFrom for Mpint { type Error = Error; - fn try_from(uint: bigint::BigUint) -> Result { + fn try_from(uint: NonZeroUint) -> Result { Mpint::try_from(&uint) } } #[cfg(feature = "bigint")] -impl TryFrom<&bigint::BigUint> for Mpint { +impl TryFrom<&NonZeroUint> for Mpint { + type Error = Error; + + fn try_from(uint: &NonZeroUint) -> Result { + Self::try_from(uint.as_ref()) + } +} + +#[cfg(feature = "bigint")] +impl TryFrom for Mpint { type Error = Error; - fn try_from(uint: &bigint::BigUint) -> Result { - let bytes = Zeroizing::new(uint.to_bytes_be()); - Mpint::from_positive_bytes(bytes.as_slice()) + fn try_from(uint: OddUint) -> Result { + Mpint::try_from(&uint) } } #[cfg(feature = "bigint")] -impl TryFrom for bigint::BigUint { +impl TryFrom<&OddUint> for Mpint { type Error = Error; - fn try_from(mpint: Mpint) -> Result { - bigint::BigUint::try_from(&mpint) + fn try_from(uint: &OddUint) -> Result { + Self::try_from(uint.as_ref()) } } #[cfg(feature = "bigint")] -impl TryFrom<&Mpint> for bigint::BigUint { +impl TryFrom for Mpint { type Error = Error; - fn try_from(mpint: &Mpint) -> Result { - mpint - .as_positive_bytes() - .map(bigint::BigUint::from_bytes_be) + fn try_from(uint: Uint) -> Result { + Mpint::try_from(&uint) + } +} + +#[cfg(feature = "bigint")] +impl TryFrom<&Uint> for Mpint { + type Error = Error; + + fn try_from(uint: &Uint) -> Result { + let bytes = Zeroizing::new(uint.to_be_bytes()); + Mpint::from_positive_bytes(&bytes) + } +} + +#[cfg(feature = "bigint")] +impl TryFrom for NonZeroUint { + type Error = Error; + + fn try_from(mpint: Mpint) -> Result { + NonZeroUint::try_from(&mpint) + } +} + +#[cfg(feature = "bigint")] +impl TryFrom<&Mpint> for NonZeroUint { + type Error = Error; + + fn try_from(mpint: &Mpint) -> Result { + let uint = Uint::try_from(mpint)?; + NonZeroUint::new(uint) + .into_option() .ok_or(Error::MpintEncoding) } } +#[cfg(feature = "bigint")] +impl TryFrom for OddUint { + type Error = Error; + + fn try_from(mpint: Mpint) -> Result { + OddUint::try_from(&mpint) + } +} + +#[cfg(feature = "bigint")] +impl TryFrom<&Mpint> for OddUint { + type Error = Error; + + fn try_from(mpint: &Mpint) -> Result { + let uint = Uint::try_from(mpint)?; + OddUint::new(uint).into_option().ok_or(Error::MpintEncoding) + } +} + +#[cfg(feature = "bigint")] +impl TryFrom for Uint { + type Error = Error; + + fn try_from(mpint: Mpint) -> Result { + Uint::try_from(&mpint) + } +} + +#[cfg(feature = "bigint")] +impl TryFrom<&Mpint> for Uint { + type Error = Error; + + fn try_from(mpint: &Mpint) -> Result { + let bytes = mpint.as_positive_bytes().ok_or(Error::MpintEncoding)?; + let bits_precision = bytes + .len() + .checked_mul(8) + .and_then(|n| u32::try_from(n).ok()) + .ok_or(Error::MpintEncoding)?; + + Ok(Uint::from_be_slice(bytes, bits_precision)?) + } +} + #[cfg(test)] mod tests { use super::Mpint; diff --git a/ssh-key/Cargo.toml b/ssh-key/Cargo.toml index fc0a4ca..bae7edb 100644 --- a/ssh-key/Cargo.toml +++ b/ssh-key/Cargo.toml @@ -20,53 +20,39 @@ rust-version = "1.85" [dependencies] cipher = { package = "ssh-cipher", version = "=0.3.0-pre.2", features = ["zeroize"], path = "../ssh-cipher" } encoding = { package = "ssh-encoding", version = "=0.3.0-pre.1", features = ["base64", "digest", "pem", "subtle", "zeroize"], path = "../ssh-encoding" } -sha2 = { version = "=0.11.0-pre.4", default-features = false } -signature = { version = "=2.3.0-pre.4", default-features = false } +sha2 = { version = "0.11.0-rc.0", default-features = false } +signature = { version = "3.0.0-rc.0", default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1", default-features = false } # optional dependencies -argon2 = { version = "=0.6.0-pre.1", optional = true, default-features = false, features = ["alloc"] } -bcrypt-pbkdf = { version = "=0.11.0-pre.1", optional = true, default-features = false, features = ["alloc"] } -bigint = { package = "num-bigint-dig", version = "0.8", optional = true, default-features = false } -dsa = { version = "=0.7.0-pre.1", optional = true, default-features = false } +argon2 = { version = "0.6.0-rc.0", optional = true, default-features = false, features = ["alloc"] } +bcrypt-pbkdf = { version = "0.11.0-rc.0", optional = true, default-features = false, features = ["alloc"] } +dsa = { version = "0.7.0-rc.0", optional = true, default-features = false, features = ["hazmat"] } ed25519-dalek = { version = "=2.2.0-pre", optional = true, default-features = false } hex = { version = "0.4", optional = true, default-features = false, features = ["alloc"] } -hmac = { version = "=0.13.0-pre.4", optional = true } +hmac = { version = "0.13.0-rc.0", optional = true } home = { version = "0.5", optional = true } -p256 = { version = "=0.14.0-pre.1", optional = true, default-features = false, features = ["ecdsa"] } -p384 = { version = "=0.14.0-pre.1", optional = true, default-features = false, features = ["ecdsa"] } -p521 = { version = "=0.14.0-pre.1", optional = true, default-features = false, features = ["ecdsa"] } -rand_core = { version = "0.6.4", optional = true, default-features = false } -rsa = { version = "=0.10.0-pre.3", optional = true, default-features = false, features = ["sha2"] } -sec1 = { version = "0.8.0-rc.3", optional = true, default-features = false, features = ["point"] } +p256 = { version = "0.14.0-pre.4", optional = true, default-features = false, features = ["ecdsa"] } +p384 = { version = "0.14.0-pre.4", optional = true, default-features = false, features = ["ecdsa"] } +p521 = { version = "0.14.0-pre.4", optional = true, default-features = false, features = ["ecdsa"] } +rand_core = { version = "0.9", optional = true, default-features = false } +rsa = { version = "0.10.0-rc.0", optional = true, default-features = false, features = ["sha2"] } +sec1 = { version = "0.8.0-rc.5", optional = true, default-features = false, features = ["point"] } serde = { version = "1.0.16", optional = true } -sha1 = { version = "=0.11.0-pre.4", optional = true, default-features = false, features = ["oid"] } +sha1 = { version = "0.11.0-rc.0", optional = true, default-features = false, features = ["oid"] } [dev-dependencies] hex-literal = "1" -rand_chacha = "0.3" +rand_chacha = "0.9" [features] default = ["ecdsa", "rand_core", "std"] -alloc = [ - "encoding/alloc", - "signature/alloc", - "zeroize/alloc", -] -std = [ - "alloc", - "p256?/std", - "p384?/std", - "p521?/std", - "rsa?/std", - "sec1?/std", - "signature/std", - "dep:home" -] +alloc = ["encoding/alloc", "signature/alloc", "zeroize/alloc", ] +std = ["alloc", "p256?/std", "p384?/std", "p521?/std", "rsa?/std", "sec1?/std", "dep:home"] crypto = ["ed25519", "p256", "p384", "p521", "rsa"] # NOTE: `dsa` is obsolete/weak -dsa = ["dep:bigint", "dep:dsa", "dep:sha1", "alloc", "encoding/bigint", "signature/rand_core"] +dsa = ["dep:dsa", "dep:sha1", "alloc", "encoding/bigint", "signature/rand_core"] ecdsa = ["dep:sec1"] ed25519 = ["dep:ed25519-dalek", "rand_core"] encryption = [ @@ -78,12 +64,12 @@ encryption = [ "cipher/chacha20poly1305", "rand_core" ] -getrandom = ["rand_core/getrandom"] +getrandom = ["rand_core/os_rng"] # TODO(tarcieri): rename feature p256 = ["dep:p256", "ecdsa"] p384 = ["dep:p384", "ecdsa"] p521 = ["dep:p521", "ecdsa"] ppk = ["dep:hex", "alloc", "cipher/aes-cbc", "dep:hmac", "dep:argon2", "dep:sha1"] -rsa = ["dep:bigint", "dep:rsa", "alloc", "encoding/bigint", "rand_core"] +rsa = ["dep:rsa", "alloc", "encoding/bigint", "rand_core"] sha1 = ["dep:sha1"] tdes = ["cipher/tdes", "encryption"] diff --git a/ssh-key/src/certificate/builder.rs b/ssh-key/src/certificate/builder.rs index 2a2e12c..5254c4d 100644 --- a/ssh-key/src/certificate/builder.rs +++ b/ssh-key/src/certificate/builder.rs @@ -5,7 +5,7 @@ use crate::{Result, Signature, SigningKey, public}; use alloc::{string::String, vec::Vec}; #[cfg(feature = "rand_core")] -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; #[cfg(feature = "std")] use {super::UnixTime, std::time::SystemTime}; @@ -43,16 +43,16 @@ use crate::PrivateKey; doc = " ```ignore" )] /// # fn main() -> Result<(), Box> { -/// use ssh_key::{Algorithm, PrivateKey, certificate, rand_core::OsRng}; +/// use ssh_key::{Algorithm, PrivateKey, certificate, rand_core::{TryRngCore, OsRng}}; /// use std::time::{SystemTime, UNIX_EPOCH}; /// /// // Generate the certificate authority's private key -/// let ca_key = PrivateKey::random(&mut OsRng, Algorithm::Ed25519)?; +/// let ca_key = PrivateKey::random(&mut OsRng.unwrap_err(), Algorithm::Ed25519)?; /// /// // Generate a "subject" key to be signed by the certificate authority. /// // Normally a user or host would do this locally and give the certificate /// // authority the public key. -/// let subject_private_key = PrivateKey::random(&mut OsRng, Algorithm::Ed25519)?; +/// let subject_private_key = PrivateKey::random(&mut OsRng.unwrap_err(), Algorithm::Ed25519)?; /// let subject_public_key = subject_private_key.public_key(); /// /// // Create certificate validity window @@ -61,7 +61,7 @@ use crate::PrivateKey; /// /// // Initialize certificate builder /// let mut cert_builder = certificate::Builder::new_with_random_nonce( -/// &mut OsRng, +/// &mut OsRng.unwrap_err(), /// subject_public_key, /// valid_after, /// valid_before, @@ -146,7 +146,7 @@ impl Builder { /// provided random number generator. #[cfg(feature = "rand_core")] pub fn new_with_random_nonce( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, public_key: impl Into, valid_after: u64, valid_before: u64, diff --git a/ssh-key/src/error.rs b/ssh-key/src/error.rs index b208188..5a884d1 100644 --- a/ssh-key/src/error.rs +++ b/ssh-key/src/error.rs @@ -73,6 +73,10 @@ pub enum Error { #[cfg(feature = "ppk")] Ppk(PpkParseError), + /// Random number generator errors. + #[cfg(feature = "rand_core")] + RngFailure, + /// Invalid timestamp (e.g. in a certificate) Time, @@ -114,6 +118,8 @@ impl fmt::Display for Error { #[cfg(feature = "ppk")] Error::Ppk(err) => write!(f, "PPK parsing error: {err}"), Error::PublicKey => write!(f, "public key is incorrect"), + #[cfg(feature = "rand_core")] + Error::RngFailure => write!(f, "random number generator failure"), Error::Time => write!(f, "invalid time"), Error::TrailingData { remaining } => write!( f, @@ -177,15 +183,14 @@ impl From for Error { } } -// TODO(tarcieri): avoid special casing this when `signature` supports `core::error::Error` -#[cfg(not(feature = "std"))] +#[cfg(not(feature = "alloc"))] impl From for Error { fn from(_: signature::Error) -> Error { Error::Crypto } } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl From for Error { fn from(err: signature::Error) -> Error { use core::error::Error as _; @@ -196,15 +201,14 @@ impl From for Error { } } -// TODO(tarcieri): avoid special casing this when `signature` supports `core::error::Error` -#[cfg(not(feature = "std"))] +#[cfg(not(feature = "alloc"))] impl From for signature::Error { fn from(_: Error) -> signature::Error { signature::Error::new() } } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl From for signature::Error { fn from(err: Error) -> signature::Error { signature::Error::from_source(err) @@ -225,6 +229,13 @@ impl From for Error { } } +#[cfg(any(feature = "dsa", feature = "rsa"))] +impl From for Error { + fn from(err: encoding::bigint::DecodeError) -> Error { + encoding::Error::from(err).into() + } +} + #[cfg(feature = "rsa")] impl From for Error { fn from(_: rsa::errors::Error) -> Error { diff --git a/ssh-key/src/kdf.rs b/ssh-key/src/kdf.rs index 9eb47e2..dff4472 100644 --- a/ssh-key/src/kdf.rs +++ b/ssh-key/src/kdf.rs @@ -9,7 +9,7 @@ use encoding::{CheckedSum, Decode, Encode, Reader, Writer}; use alloc::vec::Vec; #[cfg(feature = "encryption")] -use {crate::Cipher, bcrypt_pbkdf::bcrypt_pbkdf, rand_core::CryptoRngCore, zeroize::Zeroizing}; +use {crate::Cipher, bcrypt_pbkdf::bcrypt_pbkdf, rand_core::TryCryptoRng, zeroize::Zeroizing}; /// Default number of rounds to use for bcrypt-pbkdf. #[cfg(feature = "encryption")] @@ -40,9 +40,10 @@ pub enum Kdf { impl Kdf { /// Initialize KDF configuration for the given algorithm. #[cfg(feature = "encryption")] - pub fn new(algorithm: KdfAlg, rng: &mut impl CryptoRngCore) -> Result { + pub fn new(algorithm: KdfAlg, rng: &mut R) -> Result { let mut salt = vec![0u8; DEFAULT_SALT_SIZE]; - rng.fill_bytes(&mut salt); + rng.try_fill_bytes(&mut salt) + .map_err(|_| Error::RngFailure)?; match algorithm { KdfAlg::None => { diff --git a/ssh-key/src/private.rs b/ssh-key/src/private.rs index 71ce00b..f0ee750 100644 --- a/ssh-key/src/private.rs +++ b/ssh-key/src/private.rs @@ -65,10 +65,10 @@ doc = " ```ignore" )] //! # fn main() -> Result<(), Box> { -//! use ssh_key::{Algorithm, PrivateKey, rand_core::OsRng}; +//! use ssh_key::{Algorithm, PrivateKey, rand_core::{OsRng, TryRngCore}}; //! //! // Generate a random key -//! let unencrypted_key = PrivateKey::random(&mut OsRng, Algorithm::Ed25519)?; +//! let unencrypted_key = PrivateKey::random(&mut OsRng.unwrap_err(), Algorithm::Ed25519)?; //! //! // WARNING: don't hardcode passwords, and this one's bad anyway //! let password = "hunter42"; @@ -97,9 +97,9 @@ doc = " ```ignore" )] //! # fn main() -> Result<(), Box> { -//! use ssh_key::{Algorithm, PrivateKey, rand_core::OsRng}; +//! use ssh_key::{Algorithm, PrivateKey, rand_core::{OsRng, TryRngCore}}; //! -//! let private_key = PrivateKey::random(&mut OsRng, Algorithm::Ed25519)?; +//! let private_key = PrivateKey::random(&mut OsRng.unwrap_err(), Algorithm::Ed25519)?; //! # Ok(()) //! # } //! ``` @@ -154,8 +154,11 @@ use { zeroize::Zeroizing, }; +#[cfg(feature = "encryption")] +use rand_core::TryCryptoRng; + #[cfg(feature = "rand_core")] -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; #[cfg(feature = "std")] use std::{fs, path::Path}; @@ -395,9 +398,9 @@ impl PrivateKey { /// /// Returns [`Error::Encrypted`] if the private key is already encrypted. #[cfg(feature = "encryption")] - pub fn encrypt( + pub fn encrypt( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, password: impl AsRef<[u8]>, ) -> Result { self.encrypt_with_cipher(rng, Cipher::Aes256Ctr, password) @@ -408,13 +411,13 @@ impl PrivateKey { /// /// Returns [`Error::Encrypted`] if the private key is already encrypted. #[cfg(feature = "encryption")] - pub fn encrypt_with_cipher( + pub fn encrypt_with_cipher( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, cipher: Cipher, password: impl AsRef<[u8]>, ) -> Result { - let checkint = rng.next_u32(); + let checkint = rng.try_next_u32().map_err(|_| Error::RngFailure)?; self.encrypt_with( cipher, @@ -511,8 +514,9 @@ impl PrivateKey { /// - `Error::AlgorithmUnknown` if the algorithm is unsupported. #[cfg(feature = "rand_core")] #[allow(unreachable_code, unused_variables)] - pub fn random(rng: &mut impl CryptoRngCore, algorithm: Algorithm) -> Result { + pub fn random(rng: &mut R, algorithm: Algorithm) -> Result { let checkint = rng.next_u32(); + let key_data = match algorithm { #[cfg(feature = "dsa")] Algorithm::Dsa => KeypairData::from(DsaKeypair::random(rng)?), diff --git a/ssh-key/src/private/dsa.rs b/ssh-key/src/private/dsa.rs index f6c59ff..8d28e8e 100644 --- a/ssh-key/src/private/dsa.rs +++ b/ssh-key/src/private/dsa.rs @@ -6,8 +6,11 @@ use encoding::{CheckedSum, Decode, Encode, Reader, Writer}; use subtle::{Choice, ConstantTimeEq}; use zeroize::Zeroize; +#[cfg(feature = "dsa")] +use encoding::Uint; + #[cfg(all(feature = "dsa", feature = "rand_core"))] -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; /// Digital Signature Algorithm (DSA) private key. /// @@ -93,20 +96,20 @@ impl Drop for DsaPrivateKey { } #[cfg(feature = "dsa")] -impl TryFrom for dsa::BigUint { +impl TryFrom for Uint { type Error = Error; - fn try_from(key: DsaPrivateKey) -> Result { - Ok(dsa::BigUint::try_from(&key.inner)?) + fn try_from(key: DsaPrivateKey) -> Result { + Ok(Uint::try_from(&key.inner)?) } } #[cfg(feature = "dsa")] -impl TryFrom<&DsaPrivateKey> for dsa::BigUint { +impl TryFrom<&DsaPrivateKey> for Uint { type Error = Error; - fn try_from(key: &DsaPrivateKey) -> Result { - Ok(dsa::BigUint::try_from(&key.inner)?) + fn try_from(key: &DsaPrivateKey) -> Result { + Ok(Uint::try_from(&key.inner)?) } } @@ -148,7 +151,7 @@ impl DsaKeypair { /// Generate a random DSA private key. #[cfg(all(feature = "dsa", feature = "rand_core"))] - pub fn random(rng: &mut impl CryptoRngCore) -> Result { + pub fn random(rng: &mut R) -> Result { let components = dsa::Components::generate(rng, Self::KEY_SIZE); dsa::SigningKey::generate(rng, components).try_into() } @@ -241,7 +244,7 @@ impl TryFrom<&DsaKeypair> for dsa::SigningKey { fn try_from(key: &DsaKeypair) -> Result { Ok(dsa::SigningKey::from_components( dsa::VerifyingKey::try_from(&key.public)?, - dsa::BigUint::try_from(&key.private)?, + key.private.as_mpint().try_into()?, )?) } } diff --git a/ssh-key/src/private/ecdsa.rs b/ssh-key/src/private/ecdsa.rs index a84fa7b..3edb488 100644 --- a/ssh-key/src/private/ecdsa.rs +++ b/ssh-key/src/private/ecdsa.rs @@ -8,7 +8,7 @@ use subtle::{Choice, ConstantTimeEq}; use zeroize::Zeroize; #[cfg(feature = "rand_core")] -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; /// Elliptic Curve Digital Signature Algorithm (ECDSA) private key. #[derive(Clone)] @@ -201,7 +201,7 @@ impl EcdsaKeypair { /// Generate a random ECDSA private key. #[cfg(feature = "rand_core")] #[allow(unused_variables)] - pub fn random(rng: &mut impl CryptoRngCore, curve: EcdsaCurve) -> Result { + pub fn random(rng: &mut R, curve: EcdsaCurve) -> Result { match curve { #[cfg(feature = "p256")] EcdsaCurve::NistP256 => { diff --git a/ssh-key/src/private/ed25519.rs b/ssh-key/src/private/ed25519.rs index 245bcdd..06f8d0c 100644 --- a/ssh-key/src/private/ed25519.rs +++ b/ssh-key/src/private/ed25519.rs @@ -9,7 +9,7 @@ use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, Zeroizing}; #[cfg(feature = "rand_core")] -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; /// Ed25519 private key. // TODO(tarcieri): use `ed25519::PrivateKey`? (doesn't exist yet) @@ -22,7 +22,7 @@ impl Ed25519PrivateKey { /// Generate a random Ed25519 private key. #[cfg(feature = "rand_core")] - pub fn random(rng: &mut impl CryptoRngCore) -> Self { + pub fn random(rng: &mut R) -> Self { let mut key_bytes = [0u8; Self::BYTE_SIZE]; rng.fill_bytes(&mut key_bytes); Self(key_bytes) @@ -157,7 +157,7 @@ impl Ed25519Keypair { /// Generate a random Ed25519 private keypair. #[cfg(feature = "ed25519")] - pub fn random(rng: &mut impl CryptoRngCore) -> Self { + pub fn random(rng: &mut R) -> Self { Ed25519PrivateKey::random(rng).into() } diff --git a/ssh-key/src/private/rsa.rs b/ssh-key/src/private/rsa.rs index 478b9c3..db82c99 100644 --- a/ssh-key/src/private/rsa.rs +++ b/ssh-key/src/private/rsa.rs @@ -8,7 +8,8 @@ use zeroize::Zeroize; #[cfg(feature = "rsa")] use { - rand_core::CryptoRngCore, + encoding::{OddUint, Uint}, + rand_core::CryptoRng, rsa::{ pkcs1v15, traits::{PrivateKeyParts, PublicKeyParts}, @@ -143,7 +144,7 @@ impl RsaKeypair { /// Generate a random RSA keypair of the given size. #[cfg(feature = "rsa")] - pub fn random(rng: &mut impl CryptoRngCore, bit_size: usize) -> Result { + pub fn random(rng: &mut R, bit_size: usize) -> Result { if bit_size >= Self::MIN_KEY_SIZE { rsa::RsaPrivateKey::new(rng, bit_size)?.try_into() } else { @@ -251,12 +252,12 @@ impl TryFrom<&RsaKeypair> for rsa::RsaPrivateKey { fn try_from(key: &RsaKeypair) -> Result { let ret = rsa::RsaPrivateKey::from_components( - rsa::BigUint::try_from(key.public.n())?, - rsa::BigUint::try_from(key.public.e())?, - rsa::BigUint::try_from(&key.private.d)?, + OddUint::try_from(key.public.n())?, + Uint::try_from(key.public.e())?, + Uint::try_from(&key.private.d)?, vec![ - rsa::BigUint::try_from(&key.private.p)?, - rsa::BigUint::try_from(&key.private.q)?, + Uint::try_from(&key.private.p)?, + Uint::try_from(&key.private.q)?, ], )?; diff --git a/ssh-key/src/public/dsa.rs b/ssh-key/src/public/dsa.rs index a25c117..40da17e 100644 --- a/ssh-key/src/public/dsa.rs +++ b/ssh-key/src/public/dsa.rs @@ -4,6 +4,9 @@ use crate::{Error, Mpint, Result}; use core::hash::{Hash, Hasher}; use encoding::{CheckedSum, Decode, Encode, Reader, Writer}; +#[cfg(feature = "dsa")] +use encoding::{NonZeroUint, OddUint}; + /// Digital Signature Algorithm (DSA) public key. /// /// Described in [FIPS 186-4 ยง 4.1](https://csrc.nist.gov/publications/detail/fips/186/4/final). @@ -116,14 +119,13 @@ impl TryFrom<&DsaPublicKey> for dsa::VerifyingKey { type Error = Error; fn try_from(key: &DsaPublicKey) -> Result { - let components = dsa::Components::from_components( - dsa::BigUint::try_from(&key.p)?, - dsa::BigUint::try_from(&key.q)?, - dsa::BigUint::try_from(&key.g)?, - )?; - - dsa::VerifyingKey::from_components(components, dsa::BigUint::try_from(&key.y)?) - .map_err(|_| Error::Crypto) + let p = OddUint::try_from(&key.p)?; + let q = NonZeroUint::try_from(&key.q)?; + let g = NonZeroUint::try_from(&key.g)?; + let y = NonZeroUint::try_from(&key.y)?; + + let components = dsa::Components::from_components(p, q, g)?; + dsa::VerifyingKey::from_components(components, y).map_err(|_| Error::Crypto) } } diff --git a/ssh-key/src/public/rsa.rs b/ssh-key/src/public/rsa.rs index 624d096..7622138 100644 --- a/ssh-key/src/public/rsa.rs +++ b/ssh-key/src/public/rsa.rs @@ -7,6 +7,7 @@ use encoding::{CheckedSum, Decode, Encode, Reader, Writer}; #[cfg(feature = "rsa")] use { crate::private::RsaKeypair, + encoding::Uint, rsa::{pkcs1v15, traits::PublicKeyParts}, sha2::{Digest, digest::const_oid::AssociatedOid}, }; @@ -111,11 +112,9 @@ impl TryFrom<&RsaPublicKey> for rsa::RsaPublicKey { type Error = Error; fn try_from(key: &RsaPublicKey) -> Result { - let ret = rsa::RsaPublicKey::new( - rsa::BigUint::try_from(&key.n)?, - rsa::BigUint::try_from(&key.e)?, - ) - .map_err(|_| Error::Crypto)?; + let n = Uint::try_from(&key.n)?; + let e = Uint::try_from(&key.e)?; + let ret = rsa::RsaPublicKey::new(n, e).map_err(|_| Error::Crypto)?; if ret.size().saturating_mul(8) >= RsaPublicKey::MIN_KEY_SIZE { Ok(ret) diff --git a/ssh-key/src/signature.rs b/ssh-key/src/signature.rs index a55c081..d30a876 100644 --- a/ssh-key/src/signature.rs +++ b/ssh-key/src/signature.rs @@ -12,7 +12,7 @@ use crate::{private::Ed25519Keypair, public::Ed25519PublicKey}; #[cfg(feature = "dsa")] use { crate::{private::DsaKeypair, public::DsaPublicKey}, - bigint::BigUint, + encoding::{NonZeroUint, Uint}, signature::{DigestSigner, DigestVerifier}, }; @@ -331,13 +331,13 @@ impl Signer for DsaKeypair { .map_err(|_| signature::Error::new())?; // Encode the format specified in RFC4253 section 6.6: two raw 80-bit integers concatenated - let mut data = Vec::new(); + let mut data = Vec::with_capacity(DSA_SIGNATURE_SIZE); for component in [signature.r(), signature.s()] { - let mut bytes = component.to_bytes_be(); + let bytes = component.to_be_bytes_trimmed_vartime(); let pad_len = (DSA_SIGNATURE_SIZE / 2).saturating_sub(bytes.len()); data.extend(iter::repeat(0).take(pad_len)); - data.append(&mut bytes); + data.extend_from_slice(&bytes); } debug_assert_eq!(data.len(), DSA_SIGNATURE_SIZE); @@ -354,15 +354,7 @@ impl Verifier for DsaPublicKey { fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> { match signature.algorithm { Algorithm::Dsa => { - let data = signature.data.as_slice(); - if data.len() != DSA_SIGNATURE_SIZE { - return Err(signature::Error::new()); - } - let (r, s) = data.split_at(DSA_SIGNATURE_SIZE / 2); - let signature = dsa::Signature::from_components( - BigUint::from_bytes_be(r), - BigUint::from_bytes_be(s), - )?; + let signature = dsa::Signature::try_from(signature)?; dsa::VerifyingKey::try_from(self)? .verify_digest(Sha1::new_with_prefix(message), &signature) .map_err(|_| signature::Error::new()) @@ -372,6 +364,44 @@ impl Verifier for DsaPublicKey { } } +#[cfg(feature = "dsa")] +impl TryFrom for dsa::Signature { + type Error = Error; + + fn try_from(signature: Signature) -> Result { + dsa::Signature::try_from(&signature) + } +} + +#[cfg(feature = "dsa")] +impl TryFrom<&Signature> for dsa::Signature { + type Error = Error; + + fn try_from(signature: &Signature) -> Result { + let data = signature.data.as_slice(); + if data.len() != DSA_SIGNATURE_SIZE { + return Err(encoding::Error::Length.into()); + } + + let component_size = DSA_SIGNATURE_SIZE / 2; + let component_bits = component_size.saturating_mul(8) as u32; + let components = data.split_at(component_size); + + let r = Uint::from_be_slice(components.0, component_bits)?; + let s = Uint::from_be_slice(components.1, component_bits)?; + let signature = Self::from_components( + NonZeroUint::new(r) + .into_option() + .ok_or(encoding::Error::MpintEncoding)?, + NonZeroUint::new(s) + .into_option() + .ok_or(encoding::Error::MpintEncoding)?, + ); + + Ok(signature) + } +} + #[cfg(feature = "ed25519")] impl TryFrom for ed25519_dalek::Signature { type Error = Error; @@ -867,7 +897,7 @@ mod tests { use encoding::Decode as _; use signature::{Signer as _, Verifier as _}; - fn check_signature_component_lens( + fn check_signature_component_lengths( keypair: &DsaKeypair, data: &[u8], r_len: usize, @@ -881,7 +911,7 @@ mod tests { .try_sign_digest(Sha1::new_with_prefix(data)) .expect("valid DSA signature"); - let r = signature.r().to_bytes_be(); + let r = signature.r().to_be_bytes_trimmed_vartime(); assert_eq!( r.len(), r_len, @@ -889,7 +919,7 @@ mod tests { r.len(), r_len ); - let s = signature.s().to_bytes_be(); + let s = signature.s().to_be_bytes_trimmed_vartime(); assert_eq!( s.len(), s_len, @@ -907,7 +937,7 @@ mod tests { let data = hex!( "F0000040713d5f6fffe0000e6421ab0b3a69774d3da02fd72b107d6b32b6dad7c1660bbf507bf3eac3304cc5058f7e6f81b04239b8471459b1f3b387e2626f7eb8f6bcdd3200000006626c616465320000000e7373682d636f6e6e656374696f6e00000009686f73746261736564000000077373682d647373000001b2000000077373682d6473730000008100c161fb30c9e4e3602c8510f93bbd48d813da845dfcc75f3696e440cd019d609809608cd592b8430db901d7b43740740045b547c60fb035d69f9c64d3dfbfb13bb3edd8ccfdd44705739a639eb70f4aed16b0b8355de1b21cd9d442eff250895573a8af7ce2fb71fb062e887482dab5c68139845fb8afafc5f3819dc782920d510000001500f3fb6762430332bd5950edc5cd1ae6f17b88514f0000008061ef1394d864905e8efec3b610b7288a6522893af2a475f910796e0de47c8b065d365e942e80e471d1e6d4abdee1d3d3ede7103c6996432f1a9f9a671a31388672d63555077911fc69e641a997087260d22cdbf4965aa64bb382204f88987890ec225a5a7723a977dc1ecc5e04cf678f994692b20470adbf697489f800817b920000008100a9a6f1b65fc724d65df7441908b34af66489a4a3872cbbba25ea1bcfc83f25c4af1a62e339eefc814907cfaf0cb6d2d16996212a32a27a63013f01c57d0630f0be16c8c69d16fc25438e613b904b98aeb3e7c356fa8e75ee1d474c9f82f1280c5a6c18e9e607fcf7586eefb75ea9399da893b807375ac1396fd586bf2771619800000015746f6d61746f7373682e6c6f63616c646f6d61696e00000009746f6d61746f737368" ); - check_signature_component_lens( + check_signature_component_lengths( &keypair, &data, DSA_SIGNATURE_SIZE / 2, @@ -923,7 +953,7 @@ mod tests { "00000040713d5f6fffe0000e6421ab0b3a69774d3da02fd72b107d6b32b6dad7c1660bbf507bf3eac3304cc5058f7e6f81b04239b8471459b1f3b387e2626f7eb8f6bcdd3200000006626c616465320000000e7373682d636f6e6e656374696f6e00000009686f73746261736564000000077373682d647373000001b2000000077373682d6473730000008100c161fb30c9e4e3602c8510f93bbd48d813da845dfcc75f3696e440cd019d609809608cd592b8430db901d7b43740740045b547c60fb035d69f9c64d3dfbfb13bb3edd8ccfdd44705739a639eb70f4aed16b0b8355de1b21cd9d442eff250895573a8af7ce2fb71fb062e887482dab5c68139845fb8afafc5f3819dc782920d510000001500f3fb6762430332bd5950edc5cd1ae6f17b88514f0000008061ef1394d864905e8efec3b610b7288a6522893af2a475f910796e0de47c8b065d365e942e80e471d1e6d4abdee1d3d3ede7103c6996432f1a9f9a671a31388672d63555077911fc69e641a997087260d22cdbf4965aa64bb382204f88987890ec225a5a7723a977dc1ecc5e04cf678f994692b20470adbf697489f800817b920000008100a9a6f1b65fc724d65df7441908b34af66489a4a3872cbbba25ea1bcfc83f25c4af1a62e339eefc814907cfaf0cb6d2d16996212a32a27a63013f01c57d0630f0be16c8c69d16fc25438e613b904b98aeb3e7c356fa8e75ee1d474c9f82f1280c5a6c18e9e607fcf7586eefb75ea9399da893b807375ac1396fd586bf2771619800000015746f6d61746f7373682e6c6f63616c646f6d61696e00000009746f6d61746f737368" ); // verify that this data produces signature with `r` integer component that is less than 160 bits/20 bytes. - check_signature_component_lens( + check_signature_component_lengths( &keypair, &data, DSA_SIGNATURE_SIZE / 2 - 1, diff --git a/ssh-key/tests/encrypted_private_key.rs b/ssh-key/tests/encrypted_private_key.rs index 36f6373..febea1b 100644 --- a/ssh-key/tests/encrypted_private_key.rs +++ b/ssh-key/tests/encrypted_private_key.rs @@ -295,11 +295,11 @@ fn encode_openssh_aes256_gcm() { #[cfg(all(feature = "encryption", feature = "getrandom"))] #[test] fn encrypt_openssh_aes128_cbc() { - use rand_core::OsRng; + use rand_core::{OsRng, TryRngCore}; let key_dec = PrivateKey::from_openssh(OPENSSH_ED25519_EXAMPLE).unwrap(); let key_enc = key_dec - .encrypt_with_cipher(&mut OsRng, Cipher::Aes128Cbc, PASSWORD) + .encrypt_with_cipher(&mut OsRng.unwrap_err(), Cipher::Aes128Cbc, PASSWORD) .unwrap(); // Ensure encrypted key round trips through encoder/decoder diff --git a/ssh-protocol/src/lib.rs b/ssh-protocol/src/lib.rs index 730d91a..b1d13bf 100644 --- a/ssh-protocol/src/lib.rs +++ b/ssh-protocol/src/lib.rs @@ -24,6 +24,8 @@ pub use cipher::{self, Cipher}; pub use encoding::{self, Decode, Encode, Reader, Writer}; pub use key::{ - self, Algorithm, Fingerprint, HashAlg, Kdf, KdfAlg, Signature, certificate::Certificate, - private::PrivateKey, public::PublicKey, + self, Algorithm, Fingerprint, HashAlg, Kdf, KdfAlg, private::PrivateKey, public::PublicKey, }; + +#[cfg(feature = "alloc")] +pub use key::{Signature, certificate::Certificate};