diff --git a/Cargo.lock b/Cargo.lock index 0d1d2591..c8110bb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,12 +19,12 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" -version = "0.5.2" +version = "0.6.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "03d2d54c4d9e7006f132f615a167865bff927a79ca63d8f637237575ce0a9795" dependencies = [ - "crypto-common 0.1.6", - "generic-array", + "crypto-common 0.2.0-rc.5", + "inout 0.2.1", ] [[package]] @@ -34,19 +34,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "aes" +version = "0.9.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9e1c818b25efb32214df89b0ec22f01aa397aaeb718d1022bf0635a3bfd1a8" +dependencies = [ + "cfg-if", + "cipher 0.5.0-rc.2", "cpufeatures", ] [[package]] name = "aes-gcm" -version = "0.10.3" +version = "0.11.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +checksum = "7f5c07f414d7dc0755870f84c7900425360288d24e0eae4836f9dee19a30fa5f" dependencies = [ "aead", - "aes", - "cipher", + "aes 0.9.0-rc.2", + "cipher 0.5.0-rc.2", "ctr", "ghash", "subtle", @@ -202,12 +213,12 @@ checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "argon2" -version = "0.5.3" +version = "0.6.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +checksum = "e1a213fe583d472f454ae47407edc78848bebd950493528b1d4f7327a7dc335f" dependencies = [ "base64ct", - "blake2", + "blake2 0.11.0-rc.3", "cpufeatures", "password-hash", ] @@ -816,7 +827,7 @@ dependencies = [ "hex", "http 0.2.12", "http-body 0.4.6", - "md-5", + "md-5 0.10.6", "pin-project-lite", "sha1 0.10.6", "sha2 0.10.9", @@ -1126,6 +1137,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base16ct" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b59d472eab27ade8d770dcb11da7201c11234bef9f82ce7aa517be028d462b" + [[package]] name = "base64" version = "0.21.7" @@ -1220,6 +1237,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake2" +version = "0.11.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "679065eb2b85a078ace42411e657bef3a6afe93a40d1b9cb04e39ca303cc3f36" +dependencies = [ + "digest 0.11.0-rc.4", +] + [[package]] name = "blake3" version = "1.8.2" @@ -1488,26 +1514,26 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "99cbf41c6ec3c4b9eaf7f8f5c11a72cd7d3aa0428125c20d5ef4d09907a0f019" dependencies = [ "cfg-if", - "cipher", + "cipher 0.5.0-rc.2", "cpufeatures", + "rand_core 0.10.0-rc-2", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "c662d31454533832974f2b2b3fcbd552ed3cde94c95e614a5039d297dd97076f" dependencies = [ "aead", "chacha20", - "cipher", + "cipher 0.5.0-rc.2", "poly1305", - "zeroize", ] [[package]] @@ -1568,8 +1594,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common 0.1.6", - "inout", - "zeroize", + "inout 0.1.4", +] + +[[package]] +name = "cipher" +version = "0.5.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "155e4a260750fa4f7754649f049748aacc31db238a358d85fd721002f230f92f" +dependencies = [ + "block-buffer 0.11.0", + "crypto-common 0.2.0-rc.5", + "inout 0.2.1", ] [[package]] @@ -1950,6 +1986,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.7.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6715836b4946e8585016e80b79c7561476aff3b22f7b756778e7b109d86086c6" +dependencies = [ + "num-traits", + "rand_core 0.10.0-rc-2", + "serdect", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -1957,7 +2006,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] @@ -1967,7 +2015,20 @@ version = "0.2.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "919bd05924682a5480aec713596b9e2aabed3a0a6022fab6847f85a99e5f190a" dependencies = [ + "getrandom 0.3.4", "hybrid-array", + "rand_core 0.10.0-rc-2", +] + +[[package]] +name = "crypto-primes" +version = "0.7.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd9b2855017318a49714c07ee8895b89d3510d54fa6d86be5835de74c389609" +dependencies = [ + "crypto-bigint 0.7.0-rc.10", + "libm", + "rand_core 0.10.0-rc-2", ] [[package]] @@ -1993,11 +2054,11 @@ dependencies = [ [[package]] name = "ctr" -version = "0.9.2" +version = "0.10.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +checksum = "3d0ec605a95e78815a4c4b8040217d56d5a1ab37043851ee9e7e65b89afa00e3" dependencies = [ - "cipher", + "cipher 0.5.0-rc.2", ] [[package]] @@ -2476,7 +2537,7 @@ dependencies = [ "arrow", "arrow-buffer", "base64 0.22.1", - "blake2", + "blake2 0.10.6", "blake3", "chrono", "datafusion-common", @@ -2488,7 +2549,7 @@ dependencies = [ "hex", "itertools 0.14.0", "log", - "md-5", + "md-5 0.10.6", "rand 0.9.2", "regex", "sha2 0.10.9", @@ -2821,7 +2882,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid 0.9.6", - "pem-rfc7468", + "pem-rfc7468 0.7.0", + "zeroize", +] + +[[package]] +name = "der" +version = "0.8.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c1d73e9668ea6b6a28172aa55f3ebec38507131ce179051c8033b5c6037653" +dependencies = [ + "const-oid 0.10.1", + "pem-rfc7468 1.0.0", "zeroize", ] @@ -2949,9 +3021,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.10" +version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c478574b20020306f98d61c8ca3322d762e1ff08117422ac6106438605ea516" +checksum = "ea390c940e465846d64775e55e3115d5dc934acb953de6f6e6360bc232fe2bf7" dependencies = [ "block-buffer 0.11.0", "const-oid 0.10.1", @@ -3025,7 +3097,7 @@ dependencies = [ "flatbuffers", "futures", "md5", - "rand 0.9.2", + "rand 0.10.0-rc.5", "reqwest", "rmp-serde", "rustfs-ecstore", @@ -3133,7 +3205,7 @@ dependencies = [ "generic-array", "group 0.13.0", "hkdf", - "pem-rfc7468", + "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", @@ -3270,6 +3342,16 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "faster-hex" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7223ae2d2f179b803433d9c830478527e92b8117eab39460edae7f1614d9fb73" +dependencies = [ + "heapless", + "serde", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -3574,11 +3656,10 @@ dependencies = [ [[package]] name = "ghash" -version = "0.5.1" +version = "0.6.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +checksum = "333de57ed9494a40df4bbb866752b100819dde0d18f2264c48f5a08a85fe673d" dependencies = [ - "opaque-debug", "polyval", ] @@ -3874,6 +3955,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -3914,6 +4004,16 @@ dependencies = [ "serde", ] +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.5.0" @@ -4006,11 +4106,11 @@ dependencies = [ [[package]] name = "hmac" -version = "0.13.0-pre.5" +version = "0.13.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62c11fc82c6b89c906b4d26b7b5a305d0b3aebd4b458dd1bd0a7ed98c548a28e" +checksum = "f1c597ac7d6cc8143e30e83ef70915e7f883b18d8bec2e2b2bce47f5bbb06d57" dependencies = [ - "digest 0.11.0-pre.10", + "digest 0.11.0-rc.4", ] [[package]] @@ -4450,6 +4550,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "inout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7357b6e7aa75618c7864ebd0634b115a7218b0615f4cb1df33ac3eca23943d4" +dependencies = [ + "hybrid-array", +] + [[package]] name = "integer-encoding" version = "3.0.4" @@ -4580,7 +4689,7 @@ dependencies = [ "p384", "pem", "rand 0.8.5", - "rsa", + "rsa 0.9.8", "serde", "serde_json", "sha2 0.10.9", @@ -4918,6 +5027,16 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "md-5" +version = "0.11.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64dd2c9099caf8e29b629305199dddb1c6d981562b62c089afea54b0b4b5c333" +dependencies = [ + "cfg-if", + "digest 0.11.0-rc.4", +] + [[package]] name = "md5" version = "0.8.0" @@ -5427,12 +5546,6 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "openssl-probe" version = "0.1.6" @@ -5706,12 +5819,12 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.5.0" +version = "0.6.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +checksum = "a7d47a2d1aee5a339aa6c740d9128211a8a3d2bdf06a13e01b3f8a0b5c49b9db" dependencies = [ "base64ct", - "rand_core 0.6.4", + "rand_core 0.10.0-rc-2", "subtle", ] @@ -5755,6 +5868,16 @@ dependencies = [ "hmac 0.12.1", ] +[[package]] +name = "pbkdf2" +version = "0.13.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4c07efb9394d8d0057793c35483868c2b8102e287e9d2d4328da0da36bcb4d" +dependencies = [ + "digest 0.11.0-rc.4", + "hmac 0.13.0-rc.3", +] + [[package]] name = "pem" version = "3.0.6" @@ -5774,6 +5897,15 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pem-rfc7468" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -5905,6 +6037,16 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkcs1" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986d2e952779af96ea048f160fd9194e1751b4faea78bcf3ceb456efe008088e" +dependencies = [ + "der 0.8.0-rc.10", + "spki 0.8.0-rc.4", +] + [[package]] name = "pkcs8" version = "0.9.0" @@ -5925,6 +6067,16 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkcs8" +version = "0.11.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77089aec8290d0b7bb01b671b091095cf1937670725af4fd73d47249f03b12c0" +dependencies = [ + "der 0.8.0-rc.10", + "spki 0.8.0-rc.4", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -5961,24 +6113,22 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "d9c0749ae91cfe6e68c77c4d48802d9720ee06aed3f7100a38975fb0962d50bc" dependencies = [ "cpufeatures", - "opaque-debug", "universal-hash", ] [[package]] name = "polyval" -version = "0.6.2" +version = "0.7.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +checksum = "1ad60831c19edda4b20878a676595c357e93a9b4e6dca2ba98d75b01066b317b" dependencies = [ "cfg-if", "cpufeatures", - "opaque-debug", "universal-hash", ] @@ -6374,6 +6524,18 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand" +version = "0.10.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be866deebbade98028b705499827ad6967c8bb1e21f96a2609913c8c076e9307" +dependencies = [ + "chacha20", + "getrandom 0.3.4", + "rand_core 0.10.0-rc-2", + "serde", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -6412,6 +6574,15 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.0-rc-2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "104a23e4e8b77312a823b6b5613edbac78397e2f34320bc7ac4277013ec4478e" +dependencies = [ + "serde", +] + [[package]] name = "rayon" version = "1.11.0" @@ -6702,7 +6873,7 @@ dependencies = [ "num-bigint-dig", "num-integer", "num-traits", - "pkcs1", + "pkcs1 0.7.5", "pkcs8 0.10.2", "rand_core 0.6.4", "signature 2.2.0", @@ -6711,6 +6882,25 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rsa" +version = "0.10.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e499c52862d75a86c0024cc99dcb6d7127d15af3beae7b03573d62fab7ade08a" +dependencies = [ + "const-oid 0.10.1", + "crypto-bigint 0.7.0-rc.10", + "crypto-primes", + "digest 0.11.0-rc.4", + "pkcs1 0.8.0-rc.4", + "pkcs8 0.11.0-rc.8", + "rand_core 0.10.0-rc-2", + "signature 3.0.0-rc.5", + "spki 0.8.0-rc.4", + "subtle", + "zeroize", +] + [[package]] name = "rumqttc" version = "0.25.0" @@ -6883,7 +7073,7 @@ dependencies = [ "chrono", "futures", "heed", - "rand 0.9.2", + "rand 0.10.0-rc.5", "reqwest", "rustfs-common", "rustfs-ecstore", @@ -6909,7 +7099,8 @@ name = "rustfs-appauth" version = "0.0.5" dependencies = [ "base64-simd", - "rsa", + "rand 0.10.0-rc.5", + "rsa 0.10.0-rc.10", "serde", "serde_json", ] @@ -6943,10 +7134,10 @@ dependencies = [ "bytes", "crc-fast", "http 1.3.1", - "md-5", + "md-5 0.11.0-rc.3", "pretty_assertions", - "sha1 0.10.6", - "sha2 0.10.9", + "sha1 0.11.0-rc.3", + "sha2 0.11.0-rc.3", ] [[package]] @@ -6982,10 +7173,10 @@ dependencies = [ "cfg-if", "chacha20poly1305", "jsonwebtoken", - "pbkdf2", - "rand 0.9.2", + "pbkdf2 0.13.0-rc.2", + "rand 0.10.0-rc.5", "serde_json", - "sha2 0.10.9", + "sha2 0.11.0-rc.3", "test-case", "thiserror 2.0.17", "time", @@ -7010,19 +7201,20 @@ dependencies = [ "chrono", "criterion", "enumset", + "faster-hex", "flatbuffers", "futures", "glob", "google-cloud-auth", "google-cloud-storage", "hex-simd", - "hmac 0.12.1", + "hmac 0.13.0-rc.3", "http 1.3.1", "hyper 1.7.0", "hyper-rustls 0.27.7", "hyper-util", "lazy_static", - "md-5", + "md-5 0.11.0-rc.3", "moka", "nix 0.30.1", "num_cpus", @@ -7030,7 +7222,7 @@ dependencies = [ "path-absolutize", "pin-project-lite", "quick-xml 0.38.3", - "rand 0.9.2", + "rand 0.10.0-rc.5", "reed-solomon-simd", "regex", "reqwest", @@ -7053,8 +7245,8 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sha1 0.10.6", - "sha2 0.10.9", + "sha1 0.11.0-rc.3", + "sha2 0.11.0-rc.3", "shadow-rs", "smallvec", "temp-env", @@ -7105,7 +7297,7 @@ dependencies = [ "base64-simd", "futures", "jsonwebtoken", - "rand 0.9.2", + "rand 0.10.0-rc.5", "rustfs-crypto", "rustfs-ecstore", "rustfs-madmin", @@ -7132,11 +7324,11 @@ dependencies = [ "md5", "moka", "once_cell", - "rand 0.9.2", + "rand 0.10.0-rc.5", "reqwest", "serde", "serde_json", - "sha2 0.10.9", + "sha2 0.11.0-rc.3", "tempfile", "thiserror 2.0.17", "tokio", @@ -7266,7 +7458,7 @@ dependencies = [ "chrono", "ipnetwork", "jsonwebtoken", - "rand 0.9.2", + "rand 0.10.0-rc.5", "regex", "reqwest", "rustfs-config", @@ -7304,19 +7496,20 @@ dependencies = [ "crc32c", "crc32fast", "crc64fast-nvme", + "faster-hex", "futures", "hex-simd", "http 1.3.1", - "md-5", + "md-5 0.11.0-rc.3", "pin-project-lite", - "rand 0.9.2", + "rand 0.10.0-rc.5", "reqwest", "rustfs-utils", "s3s", "serde", "serde_json", - "sha1 0.10.6", - "sha2 0.10.9", + "sha1 0.11.0-rc.3", + "sha2 0.11.0-rc.3", "thiserror 2.0.17", "tokio", "tokio-test", @@ -7415,16 +7608,16 @@ dependencies = [ "hashbrown 0.16.0", "hex-simd", "highway", - "hmac 0.12.1", + "hmac 0.13.0-rc.3", "http 1.3.1", "hyper 1.7.0", "libc", "local-ip-address", "lz4", - "md-5", + "md-5 0.11.0-rc.3", "netif", "nix 0.30.1", - "rand 0.9.2", + "rand 0.10.0-rc.5", "regex", "rustfs-config", "rustls 0.23.35", @@ -7432,8 +7625,8 @@ dependencies = [ "rustls-pki-types", "s3s", "serde", - "sha1 0.10.6", - "sha2 0.10.9", + "sha1 0.11.0-rc.3", + "sha2 0.11.0-rc.3", "siphasher", "snap", "sysinfo", @@ -7653,8 +7846,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "s3s" version = "0.12.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e88429868c3baa36f719ff24bd7d30101f4d94490fd37edee0046989d964099" +source = "git+https://github.com/s3s-project/s3s.git?rev=1ab064b#1ab064b6e8cfe0c36a2f763e9f6aa14b56592220" dependencies = [ "arrayvec", "async-trait", @@ -7670,14 +7862,14 @@ dependencies = [ "crc64fast-nvme", "futures", "hex-simd", - "hmac 0.13.0-pre.5", + "hmac 0.13.0-rc.3", "http 1.3.1", "http-body 1.0.1", "http-body-util", "httparse", "hyper 1.7.0", "itoa", - "md-5", + "md-5 0.11.0-rc.3", "memchr", "mime", "nom 7.1.3", @@ -7686,8 +7878,8 @@ dependencies = [ "quick-xml 0.37.5", "serde", "serde_urlencoded", - "sha1 0.11.0-pre.5", - "sha2 0.11.0-pre.5", + "sha1 0.11.0-rc.3", + "sha2 0.11.0-rc.3", "smallvec", "std-next", "subtle", @@ -8017,6 +8209,16 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "serdect" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3ef0e35b322ddfaecbc60f34ab448e157e48531288ee49fafbb053696b8ffe2" +dependencies = [ + "base16ct 0.3.0", + "serde", +] + [[package]] name = "serial_test" version = "3.2.0" @@ -8055,13 +8257,13 @@ dependencies = [ [[package]] name = "sha1" -version = "0.11.0-pre.5" +version = "0.11.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f44e40722caefdd99383c25d3ae52a1094a1951215ae76f68837ece4e7f566" +checksum = "aa1ae819b9870cadc959a052363de870944a1646932d274a4e270f64bf79e5ef" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-pre.10", + "digest 0.11.0-rc.4", ] [[package]] @@ -8077,13 +8279,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0-pre.5" +version = "0.11.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b4241d1a56954dce82cecda5c8e9c794eef6f53abe5e5216bac0a0ea71ffa7" +checksum = "19d43dc0354d88b791216bb5c1bfbb60c0814460cc653ae0ebd71f286d0bd927" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-pre.10", + "digest 0.11.0-rc.4", ] [[package]] @@ -8153,6 +8355,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "3.0.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0251c9d6468f4ba853b6352b190fb7c1e405087779917c238445eb03993826" +dependencies = [ + "digest 0.11.0-rc.4", + "rand_core 0.10.0-rc-2", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -8295,6 +8507,16 @@ dependencies = [ "der 0.7.10", ] +[[package]] +name = "spki" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" +dependencies = [ + "base64ct", + "der 0.8.0-rc.10", +] + [[package]] name = "sqlparser" version = "0.58.0" @@ -9334,11 +9556,11 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "9ad6682ddb0189a4d3c2a5c54b8920ab6231ae911db53fc61a0709507bf1713b" dependencies = [ - "crypto-common 0.1.6", + "crypto-common 0.2.0-rc.5", "subtle", ] @@ -10180,7 +10402,7 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb2a05c7c36fde6c09b08576c9f7fb4cda705990f73b58fe011abf7dfb24168b" dependencies = [ - "aes", + "aes 0.8.4", "arbitrary", "bzip2 0.6.1", "constant_time_eq", @@ -10192,7 +10414,7 @@ dependencies = [ "indexmap 2.12.0", "lzma-rust2", "memchr", - "pbkdf2", + "pbkdf2 0.12.2", "ppmd-rust", "sha1 0.10.6", "time", diff --git a/Cargo.toml b/Cargo.toml index aa843b9f..152e1bfe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -138,23 +138,23 @@ serde_urlencoded = "0.7.1" schemars = "1.1.0" # Cryptography and Security -aes-gcm = { version = "0.10.3", features = ["std"] } -argon2 = { version = "0.5.3", features = ["std"] } +aes-gcm = { version = "0.11.0-rc.2", features = ["rand_core"] } +argon2 = { version = "0.6.0-rc.2", features = ["std"] } blake3 = { version = "1.8.2" } -chacha20poly1305 = { version = "0.10.1" } +chacha20poly1305 = { version = "0.11.0-rc.2" } crc-fast = "1.3.0" crc32c = "0.6.8" crc32fast = "1.5.0" crc64fast-nvme = "1.2.0" -hmac = "0.12.1" +hmac = { version = "0.13.0-rc.3" } jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] } -pbkdf2 = "0.12.2" -rsa = { version = "0.9.8" } +pbkdf2 = "0.13.0-rc.2" +rsa = { version = "0.10.0-rc.10" } rustls = { version = "0.23.35", features = ["ring", "logging", "std", "tls12"], default-features = false } rustls-pemfile = "2.2.0" rustls-pki-types = "1.13.0" -sha1 = "0.10.6" -sha2 = "0.10.9" +sha1 = "0.11.0-rc.3" +sha2 = "0.11.0-rc.3" zeroize = { version = "1.8.2", features = ["derive"] } # Time and Date @@ -184,6 +184,7 @@ crossbeam-queue = "0.3.12" datafusion = "50.3.0" derive_builder = "0.20.2" enumset = "1.1.10" +faster-hex = "0.10.0" flate2 = "1.1.5" flexi_logger = { version = "0.31.7", features = ["trc", "dont_minimize_extra_stacks", "compress", "kv", "json"] } glob = "0.3.3" @@ -196,11 +197,11 @@ highway = { version = "1.3.0" } ipnetwork = { version = "0.21.1", features = ["serde"] } lazy_static = "1.5.0" libc = "0.2.177" -libsystemd = { version = "0.7.2" } +libsystemd = "0.7.2" local-ip-address = "0.6.5" lz4 = "1.28.1" matchit = "0.9.0" -md-5 = "0.10.6" +md-5 = "0.11.0-rc.3" md5 = "0.8.0" metrics = "0.24.2" metrics-exporter-opentelemetry = "0.1.2" @@ -218,14 +219,14 @@ path-absolutize = "3.1.1" path-clean = "1.0.1" pin-project-lite = "0.2.16" pretty_assertions = "1.4.1" -rand = "0.9.2" +rand = { version = "0.10.0-rc.5", features = ["serde"] } rayon = "1.11.0" reed-solomon-simd = { version = "3.1.0" } regex = { version = "1.12.2" } rumqttc = { version = "0.25.0" } rust-embed = { version = "8.9.0" } rustc-hash = { version = "2.1.1" } -s3s = { version = "0.12.0-rc.3", features = ["minio"] } +s3s = { git = "https://github.com/s3s-project/s3s.git", rev = "1ab064b", version = "0.12.0-rc.3", features = ["minio"] } serial_test = "3.2.0" shadow-rs = { version = "1.4.0", default-features = false } siphasher = "1.0.1" diff --git a/crates/appauth/Cargo.toml b/crates/appauth/Cargo.toml index 1d318042..ffbbbde8 100644 --- a/crates/appauth/Cargo.toml +++ b/crates/appauth/Cargo.toml @@ -29,6 +29,7 @@ base64-simd = { workspace = true } rsa = { workspace = true } serde.workspace = true serde_json.workspace = true +rand.workspace = true [lints] workspace = true diff --git a/crates/appauth/src/token.rs b/crates/appauth/src/token.rs index 6fbec0c7..377bef1d 100644 --- a/crates/appauth/src/token.rs +++ b/crates/appauth/src/token.rs @@ -12,11 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use rsa::Pkcs1v15Encrypt; use rsa::{ - RsaPrivateKey, RsaPublicKey, + Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey, pkcs8::{DecodePrivateKey, DecodePublicKey}, - rand_core::OsRng, }; use serde::{Deserialize, Serialize}; use std::io::{Error, Result}; @@ -33,8 +31,9 @@ pub struct Token { /// Returns the encrypted string processed by base64 pub fn gencode(token: &Token, key: &str) -> Result { let data = serde_json::to_vec(token)?; + let mut rng = rand::rng(); let public_key = RsaPublicKey::from_public_key_pem(key).map_err(Error::other)?; - let encrypted_data = public_key.encrypt(&mut OsRng, Pkcs1v15Encrypt, &data).map_err(Error::other)?; + let encrypted_data = public_key.encrypt(&mut rng, Pkcs1v15Encrypt, &data).map_err(Error::other)?; Ok(base64_simd::URL_SAFE_NO_PAD.encode_to_string(&encrypted_data)) } @@ -76,9 +75,10 @@ mod tests { pkcs8::{EncodePrivateKey, EncodePublicKey, LineEnding}, }; use std::time::{SystemTime, UNIX_EPOCH}; + #[test] fn test_gencode_and_parse() { - let mut rng = OsRng; + let mut rng = rand::rng(); let bits = 2048; let private_key = RsaPrivateKey::new(&mut rng, bits).expect("Failed to generate private key"); let public_key = RsaPublicKey::from(&private_key); @@ -101,7 +101,8 @@ mod tests { #[test] fn test_parse_invalid_token() { - let private_key_pem = RsaPrivateKey::new(&mut OsRng, 2048) + let mut rng = rand::rng(); + let private_key_pem = RsaPrivateKey::new(&mut rng, 2048) .expect("Failed to generate private key") .to_pkcs8_pem(LineEnding::LF) .unwrap(); diff --git a/crates/crypto/Cargo.toml b/crates/crypto/Cargo.toml index ea68e22a..f29fee53 100644 --- a/crates/crypto/Cargo.toml +++ b/crates/crypto/Cargo.toml @@ -29,7 +29,7 @@ documentation = "https://docs.rs/rustfs-crypto/latest/rustfs_crypto/" workspace = true [dependencies] -aes-gcm = { workspace = true, features = ["std"], optional = true } +aes-gcm = { workspace = true, optional = true } argon2 = { workspace = true, features = ["std"], optional = true } cfg-if = { workspace = true } chacha20poly1305 = { workspace = true, optional = true } diff --git a/crates/crypto/src/encdec/decrypt.rs b/crates/crypto/src/encdec/decrypt.rs index 42d34776..18f20a9c 100644 --- a/crates/crypto/src/encdec/decrypt.rs +++ b/crates/crypto/src/encdec/decrypt.rs @@ -19,127 +19,37 @@ pub fn decrypt_data(password: &[u8], data: &[u8]) -> Result, crate::Erro use aes_gcm::{Aes256Gcm, KeyInit as _}; use chacha20poly1305::ChaCha20Poly1305; - // 32: salt - // 1: id - // 12: nonce const HEADER_LENGTH: usize = 45; if data.len() < HEADER_LENGTH { return Err(Error::ErrUnexpectedHeader); } - let (salt, id, nonce) = (&data[..32], ID::try_from(data[32])?, &data[33..45]); - let data = &data[HEADER_LENGTH..]; + let (salt, id, nonce_slice) = (&data[..32], ID::try_from(data[32])?, &data[33..45]); + let body = &data[HEADER_LENGTH..]; match id { ID::Argon2idChaCHa20Poly1305 => { let key = id.get_key(password, salt)?; - decrypt(ChaCha20Poly1305::new_from_slice(&key)?, nonce, data) + decrypt(ChaCha20Poly1305::new_from_slice(&key)?, nonce_slice, body) } _ => { let key = id.get_key(password, salt)?; - decrypt(Aes256Gcm::new_from_slice(&key)?, nonce, data) + decrypt(Aes256Gcm::new_from_slice(&key)?, nonce_slice, body) } } } -// use argon2::{Argon2, PasswordHasher}; -// use argon2::password_hash::{SaltString}; -// use aes_gcm::{Aes256Gcm, Key, Nonce}; // For AES-GCM -// use chacha20poly1305::{ChaCha20Poly1305, Key as ChaChaKey, Nonce as ChaChaNonce}; // For ChaCha20 -// use pbkdf2::pbkdf2; -// use sha2::Sha256; -// use std::io::{self, Read}; -// use thiserror::Error; - -// #[derive(Debug, Error)] -// pub enum DecryptError { -// #[error("unexpected header")] -// UnexpectedHeader, -// #[error("invalid encryption algorithm ID")] -// InvalidAlgorithmId, -// #[error("IO error")] -// Io(#[from] io::Error), -// #[error("decryption error")] -// DecryptionError, -// } - -// pub fn decrypt_data2(password: &str, mut data: R) -> Result, DecryptError> { -// // Parse the stream header -// let mut hdr = [0u8; 32 + 1 + 8]; -// if data.read_exact(&mut hdr).is_err() { -// return Err(DecryptError::UnexpectedHeader); -// } - -// let salt = &hdr[0..32]; -// let id = hdr[32]; -// let nonce = &hdr[33..41]; - -// let key = match id { -// // Argon2id + AES-GCM -// 0x01 => { -// let salt = SaltString::encode_b64(salt).map_err(|_| DecryptError::DecryptionError)?; -// let argon2 = Argon2::default(); -// let hashed_key = argon2.hash_password(password.as_bytes(), &salt) -// .map_err(|_| DecryptError::DecryptionError)?; -// hashed_key.hash.unwrap().as_bytes().to_vec() -// } -// // Argon2id + ChaCha20Poly1305 -// 0x02 => { -// let salt = SaltString::encode_b64(salt).map_err(|_| DecryptError::DecryptionError)?; -// let argon2 = Argon2::default(); -// let hashed_key = argon2.hash_password(password.as_bytes(), &salt) -// .map_err(|_| DecryptError::DecryptionError)?; -// hashed_key.hash.unwrap().as_bytes().to_vec() -// } -// // PBKDF2 + AES-GCM -// // 0x03 => { -// // let mut key = [0u8; 32]; -// // pbkdf2::(password.as_bytes(), salt, 10000, &mut key); -// // key.to_vec() -// // } -// _ => return Err(DecryptError::InvalidAlgorithmId), -// }; - -// // Decrypt data using the corresponding cipher -// let mut encrypted_data = Vec::new(); -// data.read_to_end(&mut encrypted_data)?; - -// let plaintext = match id { -// 0x01 => { -// let cipher = Aes256Gcm::new(Key::from_slice(&key)); -// let nonce = Nonce::from_slice(nonce); -// cipher -// .decrypt(nonce, encrypted_data.as_ref()) -// .map_err(|_| DecryptError::DecryptionError)? -// } -// 0x02 => { -// let cipher = ChaCha20Poly1305::new(ChaChaKey::from_slice(&key)); -// let nonce = ChaChaNonce::from_slice(nonce); -// cipher -// .decrypt(nonce, encrypted_data.as_ref()) -// .map_err(|_| DecryptError::DecryptionError)? -// } -// 0x03 => { - -// let cipher = Aes256Gcm::new(Key::from_slice(&key)); -// let nonce = Nonce::from_slice(nonce); -// cipher -// .decrypt(nonce, encrypted_data.as_ref()) -// .map_err(|_| DecryptError::DecryptionError)? -// } -// _ => return Err(DecryptError::InvalidAlgorithmId), -// }; - -// Ok(plaintext) -// } - #[cfg(any(test, feature = "crypto"))] #[inline] fn decrypt(stream: T, nonce: &[u8], data: &[u8]) -> Result, crate::Error> { use crate::error::Error; - stream - .decrypt(aes_gcm::Nonce::from_slice(nonce), data) - .map_err(Error::ErrDecryptFailed) + use aes_gcm::AeadCore; + use aes_gcm::aead::array::Array; + use core::convert::TryFrom; + + let nonce_arr: Array::NonceSize> = + Array::try_from(nonce).map_err(|_| Error::ErrDecryptFailed(aes_gcm::aead::Error))?; + stream.decrypt(&nonce_arr, data).map_err(Error::ErrDecryptFailed) } #[cfg(not(any(test, feature = "crypto")))] diff --git a/crates/crypto/src/encdec/encrypt.rs b/crates/crypto/src/encdec/encrypt.rs index 622910c4..ad5f3668 100644 --- a/crates/crypto/src/encdec/encrypt.rs +++ b/crates/crypto/src/encdec/encrypt.rs @@ -43,7 +43,7 @@ pub fn encrypt_data(password: &[u8], data: &[u8]) -> Result, crate::Erro if native_aes() { encrypt(Aes256Gcm::new_from_slice(&key)?, &salt, id, data) } else { - encrypt(ChaCha20Poly1305::new_from_slice(&key)?, &salt, id, data) + encrypt(chacha20poly1305::ChaCha20Poly1305::new_from_slice(&key)?, &salt, id, data) } } } @@ -56,16 +56,19 @@ fn encrypt( data: &[u8], ) -> Result, crate::Error> { use crate::error::Error; - use aes_gcm::aead::rand_core::OsRng; + use aes_gcm::AeadCore; + use aes_gcm::aead::array::Array; + use rand::RngCore; - let nonce = T::generate_nonce(&mut OsRng); + let mut nonce: Array::NonceSize> = Array::default(); + rand::rng().fill_bytes(&mut nonce); let encryptor = stream.encrypt(&nonce, data).map_err(Error::ErrEncryptFailed)?; let mut ciphertext = Vec::with_capacity(salt.len() + 1 + nonce.len() + encryptor.len()); ciphertext.extend_from_slice(salt); ciphertext.push(id as u8); - ciphertext.extend_from_slice(nonce.as_slice()); + ciphertext.extend_from_slice(&nonce); ciphertext.extend_from_slice(&encryptor); Ok(ciphertext) diff --git a/crates/ecstore/Cargo.toml b/crates/ecstore/Cargo.toml index 3ea35671..c144bfb9 100644 --- a/crates/ecstore/Cargo.toml +++ b/crates/ecstore/Cargo.toml @@ -106,6 +106,7 @@ serde_urlencoded.workspace = true google-cloud-storage = { workspace = true } google-cloud-auth = { workspace = true } aws-config = { workspace = true } +faster-hex = { workspace = true } [target.'cfg(not(windows))'.dependencies] nix = { workspace = true } diff --git a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs index 45d3fecd..d7404057 100644 --- a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs +++ b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs @@ -115,10 +115,9 @@ struct ExpiryTask { impl ExpiryOp for ExpiryTask { fn op_hash(&self) -> u64 { let mut hasher = Sha256::new(); - let _ = hasher.write(format!("{}", self.obj_info.bucket).as_bytes()); - let _ = hasher.write(format!("{}", self.obj_info.name).as_bytes()); - hasher.flush(); - xxh64::xxh64(hasher.clone().finalize().as_slice(), XXHASH_SEED) + hasher.update(format!("{}", self.obj_info.bucket).as_bytes()); + hasher.update(format!("{}", self.obj_info.name).as_bytes()); + xxh64::xxh64(hasher.finalize().as_slice(), XXHASH_SEED) } fn as_any(&self) -> &dyn Any { @@ -171,10 +170,9 @@ struct FreeVersionTask(ObjectInfo); impl ExpiryOp for FreeVersionTask { fn op_hash(&self) -> u64 { let mut hasher = Sha256::new(); - let _ = hasher.write(format!("{}", self.0.transitioned_object.tier).as_bytes()); - let _ = hasher.write(format!("{}", self.0.transitioned_object.name).as_bytes()); - hasher.flush(); - xxh64::xxh64(hasher.clone().finalize().as_slice(), XXHASH_SEED) + hasher.update(format!("{}", self.0.transitioned_object.tier).as_bytes()); + hasher.update(format!("{}", self.0.transitioned_object.name).as_bytes()); + xxh64::xxh64(hasher.finalize().as_slice(), XXHASH_SEED) } fn as_any(&self) -> &dyn Any { @@ -191,10 +189,9 @@ struct NewerNoncurrentTask { impl ExpiryOp for NewerNoncurrentTask { fn op_hash(&self) -> u64 { let mut hasher = Sha256::new(); - let _ = hasher.write(format!("{}", self.bucket).as_bytes()); - let _ = hasher.write(format!("{}", self.versions[0].object_name).as_bytes()); - hasher.flush(); - xxh64::xxh64(hasher.clone().finalize().as_slice(), XXHASH_SEED) + hasher.update(format!("{}", self.bucket).as_bytes()); + hasher.update(format!("{}", self.versions[0].object_name).as_bytes()); + xxh64::xxh64(hasher.finalize().as_slice(), XXHASH_SEED) } fn as_any(&self) -> &dyn Any { @@ -415,10 +412,9 @@ struct TransitionTask { impl ExpiryOp for TransitionTask { fn op_hash(&self) -> u64 { let mut hasher = Sha256::new(); - let _ = hasher.write(format!("{}", self.obj_info.bucket).as_bytes()); - //let _ = hasher.write(format!("{}", self.obj_info.versions[0].object_name).as_bytes()); - hasher.flush(); - xxh64::xxh64(hasher.clone().finalize().as_slice(), XXHASH_SEED) + hasher.update(format!("{}", self.obj_info.bucket).as_bytes()); + // hasher.update(format!("{}", self.obj_info.versions[0].object_name).as_bytes()); + xxh64::xxh64(hasher.finalize().as_slice(), XXHASH_SEED) } fn as_any(&self) -> &dyn Any { @@ -480,7 +476,7 @@ impl TransitionState { .and_then(|s| s.parse::().ok()) .unwrap_or_else(|| std::cmp::min(num_cpus::get() as i64, 16)); let mut n = max_workers; - let tw = 8; //globalILMConfig.getTransitionWorkers(); + let tw = 8; //globalILMConfig.getTransitionWorkers(); if tw > 0 { n = tw; } @@ -760,9 +756,8 @@ pub async fn expire_transitioned_object( pub fn gen_transition_objname(bucket: &str) -> Result { let us = Uuid::new_v4().to_string(); let mut hasher = Sha256::new(); - let _ = hasher.write(format!("{}/{}", get_global_deployment_id().unwrap_or_default(), bucket).as_bytes()); - hasher.flush(); - let hash = rustfs_utils::crypto::hex(hasher.clone().finalize().as_slice()); + hasher.update(format!("{}/{}", get_global_deployment_id().unwrap_or_default(), bucket).as_bytes()); + let hash = rustfs_utils::crypto::hex(hasher.finalize().as_slice()); let obj = format!("{}/{}/{}/{}", &hash[0..16], &us[0..2], &us[2..4], &us); Ok(obj) } diff --git a/crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs b/crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs index 333fed97..26f94031 100644 --- a/crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs +++ b/crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs @@ -20,7 +20,7 @@ use sha2::{Digest, Sha256}; use std::any::Any; -use std::io::{Cursor, Write}; +use std::io::Write; use xxhash_rust::xxh64; use super::bucket_lifecycle_ops::{ExpiryOp, GLOBAL_ExpiryState, TransitionedObject}; @@ -128,10 +128,9 @@ pub struct Jentry { impl ExpiryOp for Jentry { fn op_hash(&self) -> u64 { let mut hasher = Sha256::new(); - let _ = hasher.write(format!("{}", self.tier_name).as_bytes()); - let _ = hasher.write(format!("{}", self.obj_name).as_bytes()); - hasher.flush(); - xxh64::xxh64(hasher.clone().finalize().as_slice(), XXHASH_SEED) + hasher.update(format!("{}", self.tier_name).as_bytes()); + hasher.update(format!("{}", self.obj_name).as_bytes()); + xxh64::xxh64(hasher.finalize().as_slice(), XXHASH_SEED) } fn as_any(&self) -> &dyn Any { diff --git a/crates/ecstore/src/rpc/http_auth.rs b/crates/ecstore/src/rpc/http_auth.rs index 95894d15..faad926e 100644 --- a/crates/ecstore/src/rpc/http_auth.rs +++ b/crates/ecstore/src/rpc/http_auth.rs @@ -15,7 +15,7 @@ use crate::global::get_global_action_cred; use base64::Engine as _; use base64::engine::general_purpose; -use hmac::{Hmac, Mac}; +use hmac::{Hmac, KeyInit, Mac}; use http::HeaderMap; use http::HeaderValue; use http::Method; diff --git a/crates/ecstore/src/set_disk.rs b/crates/ecstore/src/set_disk.rs index 5cf6ba11..dfb66afe 100644 --- a/crates/ecstore/src/set_disk.rs +++ b/crates/ecstore/src/set_disk.rs @@ -1323,13 +1323,13 @@ impl SetDisks { if etag_only || mod_valid { for part in meta.parts.iter() { - let _ = hasher.write(format!("part.{}", part.number).as_bytes())?; - let _ = hasher.write(format!("part.{}", part.size).as_bytes())?; + hasher.update(format!("part.{}", part.number).as_bytes()); + hasher.update(format!("part.{}", part.size).as_bytes()); } if !meta.deleted && meta.size != 0 { - let _ = hasher.write(format!("{}+{}", meta.erasure.data_blocks, meta.erasure.parity_blocks).as_bytes())?; - let _ = hasher.write(format!("{:?}", meta.erasure.distribution).as_bytes())?; + hasher.update(format!("{}+{}", meta.erasure.data_blocks, meta.erasure.parity_blocks).as_bytes()); + hasher.update(format!("{:?}", meta.erasure.distribution).as_bytes()); } if meta.is_remote() { @@ -1340,8 +1340,6 @@ impl SetDisks { // TODO: IsCompressed - hasher.flush()?; - meta_hashes[i] = Some(hex(hasher.clone().finalize().as_slice())); hasher.reset(); @@ -6553,9 +6551,11 @@ fn get_complete_multipart_md5(parts: &[CompletePart]) -> String { } let mut hasher = Md5::new(); - let _ = hasher.write(&buf); + hasher.update(&buf); - format!("{:x}-{}", hasher.finalize(), parts.len()) + let digest = hasher.finalize(); + let etag_hex = faster_hex::hex_string(digest.as_slice()); + format!("{}-{}", etag_hex, parts.len()) } pub fn canonicalize_etag(etag: &str) -> String { diff --git a/crates/kms/src/backends/local.rs b/crates/kms/src/backends/local.rs index f73abf8a..a8f28795 100644 --- a/crates/kms/src/backends/local.rs +++ b/crates/kms/src/backends/local.rs @@ -19,12 +19,12 @@ use crate::config::KmsConfig; use crate::config::LocalConfig; use crate::error::{KmsError, Result}; use crate::types::*; -use aes_gcm::aead::rand_core::RngCore; use aes_gcm::{ Aes256Gcm, Key, Nonce, - aead::{Aead, AeadCore, KeyInit, OsRng}, + aead::{Aead, KeyInit}, }; use async_trait::async_trait; +use rand::Rng; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::PathBuf; @@ -105,8 +105,9 @@ impl LocalKmsClient { hasher.update(master_key.as_bytes()); hasher.update(b"rustfs-kms-local"); // Salt to prevent rainbow tables let hash = hasher.finalize(); - - Ok(*Key::::from_slice(&hash)) + let key = Key::::try_from(hash.as_slice()) + .map_err(|_| KmsError::cryptographic_error("key", "Invalid key length"))?; + Ok(key) } /// Get the file path for a master key @@ -117,7 +118,6 @@ impl LocalKmsClient { /// Load a master key from disk async fn load_master_key(&self, key_id: &str) -> Result { let key_path = self.master_key_path(key_id); - if !key_path.exists() { return Err(KmsError::key_not_found(key_id)); } @@ -127,9 +127,16 @@ impl LocalKmsClient { // Decrypt key material if master cipher is available let _key_material = if let Some(ref cipher) = self.master_cipher { - let nonce = Nonce::from_slice(&stored_key.nonce); + if stored_key.nonce.len() != 12 { + return Err(KmsError::cryptographic_error("nonce", "Invalid nonce length")); + } + + let mut nonce_array = [0u8; 12]; + nonce_array.copy_from_slice(&stored_key.nonce); + let nonce = Nonce::from(nonce_array); + cipher - .decrypt(nonce, stored_key.encrypted_key_material.as_ref()) + .decrypt(&nonce, stored_key.encrypted_key_material.as_ref()) .map_err(|e| KmsError::cryptographic_error("decrypt", e.to_string()))? } else { stored_key.encrypted_key_material @@ -155,7 +162,10 @@ impl LocalKmsClient { // Encrypt key material if master cipher is available let (encrypted_key_material, nonce) = if let Some(ref cipher) = self.master_cipher { - let nonce = Aes256Gcm::generate_nonce(&mut OsRng); + let mut nonce_bytes = [0u8; 12]; + rand::rng().fill(&mut nonce_bytes[..]); + let nonce = Nonce::from(nonce_bytes); + let encrypted = cipher .encrypt(&nonce, key_material) .map_err(|e| KmsError::cryptographic_error("encrypt", e.to_string()))?; @@ -202,7 +212,7 @@ impl LocalKmsClient { /// Generate a random 256-bit key fn generate_key_material() -> Vec { let mut key_material = vec![0u8; 32]; // 256 bits - OsRng.fill_bytes(&mut key_material); + rand::rng().fill(&mut key_material[..]); key_material } @@ -219,9 +229,14 @@ impl LocalKmsClient { // Decrypt key material if master cipher is available let key_material = if let Some(ref cipher) = self.master_cipher { - let nonce = Nonce::from_slice(&stored_key.nonce); + if stored_key.nonce.len() != 12 { + return Err(KmsError::cryptographic_error("nonce", "Invalid nonce length")); + } + let mut nonce_array = [0u8; 12]; + nonce_array.copy_from_slice(&stored_key.nonce); + let nonce = Nonce::from(nonce_array); cipher - .decrypt(nonce, stored_key.encrypted_key_material.as_ref()) + .decrypt(&nonce, stored_key.encrypted_key_material.as_ref()) .map_err(|e| KmsError::cryptographic_error("decrypt", e.to_string()))? } else { stored_key.encrypted_key_material @@ -234,25 +249,39 @@ impl LocalKmsClient { async fn encrypt_with_master_key(&self, key_id: &str, plaintext: &[u8]) -> Result<(Vec, Vec)> { // Load the actual master key material let key_material = self.get_key_material(key_id).await?; - let cipher = Aes256Gcm::new(Key::::from_slice(&key_material)); + let key = Key::::try_from(key_material.as_slice()) + .map_err(|_| KmsError::cryptographic_error("key", "Invalid key length"))?; + let cipher = Aes256Gcm::new(&key); + + let mut nonce_bytes = [0u8; 12]; + rand::rng().fill(&mut nonce_bytes[..]); + + let nonce = Nonce::from(nonce_bytes); - let nonce = Aes256Gcm::generate_nonce(&mut OsRng); let ciphertext = cipher .encrypt(&nonce, plaintext) .map_err(|e| KmsError::cryptographic_error("encrypt", e.to_string()))?; - Ok((ciphertext, nonce.to_vec())) + Ok((ciphertext, nonce_bytes.to_vec())) } /// Decrypt data using a master key async fn decrypt_with_master_key(&self, key_id: &str, ciphertext: &[u8], nonce: &[u8]) -> Result> { + if nonce.len() != 12 { + return Err(KmsError::cryptographic_error("nonce", "Invalid nonce length")); + } // Load the actual master key material let key_material = self.get_key_material(key_id).await?; - let cipher = Aes256Gcm::new(Key::::from_slice(&key_material)); + let key = Key::::try_from(key_material.as_slice()) + .map_err(|_| KmsError::cryptographic_error("key", "Invalid key length"))?; + let cipher = Aes256Gcm::new(&key); + + let mut nonce_array = [0u8; 12]; + nonce_array.copy_from_slice(nonce); + let nonce_ref = Nonce::from(nonce_array); - let nonce = Nonce::from_slice(nonce); let plaintext = cipher - .decrypt(nonce, ciphertext) + .decrypt(&nonce_ref, ciphertext) .map_err(|e| KmsError::cryptographic_error("decrypt", e.to_string()))?; Ok(plaintext) @@ -275,7 +304,7 @@ impl KmsClient for LocalKmsClient { }; let mut plaintext_key = vec![0u8; key_length]; - OsRng.fill_bytes(&mut plaintext_key); + rand::rng().fill(&mut plaintext_key[..]); // Encrypt the data key with the master key let (encrypted_key, nonce) = self.encrypt_with_master_key(&request.master_key_id, &plaintext_key).await?; @@ -776,9 +805,14 @@ impl KmsBackend for LocalKmsBackend { // Decrypt the existing key material to preserve it let existing_key_material = if let Some(ref cipher) = self.client.master_cipher { - let nonce = Nonce::from_slice(&stored_key.nonce); + if stored_key.nonce.len() != 12 { + return Err(KmsError::cryptographic_error("nonce", "Invalid nonce length")); + } + let mut nonce_array = [0u8; 12]; + nonce_array.copy_from_slice(&stored_key.nonce); + let nonce = Nonce::from(nonce_array); cipher - .decrypt(nonce, stored_key.encrypted_key_material.as_ref()) + .decrypt(&nonce, stored_key.encrypted_key_material.as_ref()) .map_err(|e| KmsError::cryptographic_error("decrypt", e.to_string()))? } else { stored_key.encrypted_key_material diff --git a/crates/kms/src/backends/mod.rs b/crates/kms/src/backends/mod.rs index 46d9b646..03637198 100644 --- a/crates/kms/src/backends/mod.rs +++ b/crates/kms/src/backends/mod.rs @@ -20,7 +20,6 @@ use async_trait::async_trait; use std::collections::HashMap; pub mod local; - pub mod vault; /// Abstract KMS client interface that all backends must implement diff --git a/crates/kms/src/encryption/ciphers.rs b/crates/kms/src/encryption/ciphers.rs index 4d4b2053..7143bce7 100644 --- a/crates/kms/src/encryption/ciphers.rs +++ b/crates/kms/src/encryption/ciphers.rs @@ -16,12 +16,12 @@ use crate::error::{KmsError, Result}; use crate::types::EncryptionAlgorithm; -use aes_gcm::aead::rand_core::RngCore; use aes_gcm::{ Aes256Gcm, Key, Nonce, - aead::{Aead, KeyInit, OsRng}, + aead::{Aead, KeyInit}, }; use chacha20poly1305::ChaCha20Poly1305; +use rand::Rng; /// Trait for object encryption ciphers #[cfg_attr(not(test), allow(dead_code))] @@ -57,8 +57,8 @@ impl AesCipher { return Err(KmsError::invalid_key_size(32, key.len())); } - let key = Key::::from_slice(key); - let cipher = Aes256Gcm::new(key); + let key = Key::::try_from(key).map_err(|_| KmsError::cryptographic_error("key", "Invalid key length"))?; + let cipher = Aes256Gcm::new(&key); Ok(Self { cipher }) } @@ -70,12 +70,12 @@ impl ObjectCipher for AesCipher { return Err(KmsError::invalid_key_size(12, iv.len())); } - let nonce = Nonce::from_slice(iv); + let nonce = Nonce::try_from(iv).map_err(|_| KmsError::cryptographic_error("nonce", "Invalid nonce length"))?; // AES-GCM includes the tag in the ciphertext let ciphertext_with_tag = self .cipher - .encrypt(nonce, aes_gcm::aead::Payload { msg: plaintext, aad }) + .encrypt(&nonce, aes_gcm::aead::Payload { msg: plaintext, aad }) .map_err(KmsError::from_aes_gcm_error)?; // Split ciphertext and tag @@ -98,7 +98,7 @@ impl ObjectCipher for AesCipher { return Err(KmsError::invalid_key_size(self.tag_size(), tag.len())); } - let nonce = Nonce::from_slice(iv); + let nonce = Nonce::try_from(iv).map_err(|_| KmsError::cryptographic_error("nonce", "Invalid nonce length"))?; // Combine ciphertext and tag for AES-GCM let mut ciphertext_with_tag = ciphertext.to_vec(); @@ -107,7 +107,7 @@ impl ObjectCipher for AesCipher { let plaintext = self .cipher .decrypt( - nonce, + &nonce, aes_gcm::aead::Payload { msg: &ciphertext_with_tag, aad, @@ -147,8 +147,8 @@ impl ChaCha20Cipher { return Err(KmsError::invalid_key_size(32, key.len())); } - let key = chacha20poly1305::Key::from_slice(key); - let cipher = ChaCha20Poly1305::new(key); + let key = chacha20poly1305::Key::try_from(key).map_err(|_| KmsError::cryptographic_error("key", "Invalid key length"))?; + let cipher = ChaCha20Poly1305::new(&key); Ok(Self { cipher }) } @@ -160,12 +160,13 @@ impl ObjectCipher for ChaCha20Cipher { return Err(KmsError::invalid_key_size(12, iv.len())); } - let nonce = chacha20poly1305::Nonce::from_slice(iv); + let nonce = + chacha20poly1305::Nonce::try_from(iv).map_err(|_| KmsError::cryptographic_error("nonce", "Invalid nonce length"))?; // ChaCha20-Poly1305 includes the tag in the ciphertext let ciphertext_with_tag = self .cipher - .encrypt(nonce, chacha20poly1305::aead::Payload { msg: plaintext, aad }) + .encrypt(&nonce, chacha20poly1305::aead::Payload { msg: plaintext, aad }) .map_err(KmsError::from_chacha20_error)?; // Split ciphertext and tag @@ -188,7 +189,8 @@ impl ObjectCipher for ChaCha20Cipher { return Err(KmsError::invalid_key_size(self.tag_size(), tag.len())); } - let nonce = chacha20poly1305::Nonce::from_slice(iv); + let nonce = + chacha20poly1305::Nonce::try_from(iv).map_err(|_| KmsError::cryptographic_error("nonce", "Invalid nonce length"))?; // Combine ciphertext and tag for ChaCha20-Poly1305 let mut ciphertext_with_tag = ciphertext.to_vec(); @@ -197,7 +199,7 @@ impl ObjectCipher for ChaCha20Cipher { let plaintext = self .cipher .decrypt( - nonce, + &nonce, chacha20poly1305::aead::Payload { msg: &ciphertext_with_tag, aad, @@ -241,7 +243,7 @@ pub fn generate_iv(algorithm: &EncryptionAlgorithm) -> Vec { }; let mut iv = vec![0u8; iv_size]; - OsRng.fill_bytes(&mut iv); + rand::rng().fill(&mut iv[..]); iv } diff --git a/crates/rio/Cargo.toml b/crates/rio/Cargo.toml index b5c7ba10..cba92d8e 100644 --- a/crates/rio/Cargo.toml +++ b/crates/rio/Cargo.toml @@ -39,6 +39,7 @@ serde = { workspace = true } bytes.workspace = true reqwest.workspace = true tokio-util.workspace = true +faster-hex.workspace = true futures.workspace = true rustfs-utils = { workspace = true, features = ["io", "hash", "compress"] } serde_json.workspace = true diff --git a/crates/rio/src/encrypt_reader.rs b/crates/rio/src/encrypt_reader.rs index d6dd24c8..01521ac8 100644 --- a/crates/rio/src/encrypt_reader.rs +++ b/crates/rio/src/encrypt_reader.rs @@ -20,6 +20,7 @@ use aes_gcm::aead::Aead; use aes_gcm::{Aes256Gcm, KeyInit, Nonce}; use pin_project_lite::pin_project; use rustfs_utils::{put_uvarint, put_uvarint_len}; +use std::io::Error; use std::pin::Pin; use std::task::{Context, Poll}; use tokio::io::{AsyncRead, ReadBuf}; @@ -98,13 +99,13 @@ where } else { // Encrypt the chunk let cipher = Aes256Gcm::new_from_slice(this.key).expect("key"); - let nonce = Nonce::from_slice(this.nonce); + let nonce = Nonce::try_from(this.nonce.as_slice()).map_err(|_| Error::other("invalid nonce length"))?; let plaintext = &temp_buf.filled()[..n]; let plaintext_len = plaintext.len(); let crc = crc32fast::hash(plaintext); let ciphertext = cipher - .encrypt(nonce, plaintext) - .map_err(|e| std::io::Error::other(format!("encrypt error: {e}")))?; + .encrypt(&nonce, plaintext) + .map_err(|e| Error::other(format!("encrypt error: {e}")))?; let int_len = put_uvarint_len(plaintext_len as u64); let clen = int_len + ciphertext.len() + 4; // Header: 8 bytes @@ -352,7 +353,7 @@ where let Some(payload_len) = len.checked_sub(4) else { tracing::error!("invalid encrypted block length: typ={} len={} header={:?}", typ, len, this.header_buf); - return Poll::Ready(Err(std::io::Error::other("Invalid encrypted block length"))); + return Poll::Ready(Err(Error::other("Invalid encrypted block length"))); }; if this.ciphertext_buf.is_none() { @@ -390,10 +391,10 @@ where let ciphertext = &ciphertext_buf[uvarint_len as usize..]; let cipher = Aes256Gcm::new_from_slice(this.key).expect("key"); - let nonce = Nonce::from_slice(this.current_nonce); + let nonce = Nonce::try_from(this.current_nonce.as_slice()).map_err(|_| Error::other("invalid nonce length"))?; let plaintext = cipher - .decrypt(nonce, ciphertext) - .map_err(|e| std::io::Error::other(format!("decrypt error: {e}")))?; + .decrypt(&nonce, ciphertext) + .map_err(|e| Error::other(format!("decrypt error: {e}")))?; debug!( part = *this.current_part, @@ -405,7 +406,7 @@ where this.ciphertext_buf.take(); *this.ciphertext_read = 0; *this.ciphertext_len = 0; - return Poll::Ready(Err(std::io::Error::other("Plaintext length mismatch"))); + return Poll::Ready(Err(Error::other("Plaintext length mismatch"))); } let actual_crc = crc32fast::hash(&plaintext); @@ -413,7 +414,7 @@ where this.ciphertext_buf.take(); *this.ciphertext_read = 0; *this.ciphertext_len = 0; - return Poll::Ready(Err(std::io::Error::other("CRC32 mismatch"))); + return Poll::Ready(Err(Error::other("CRC32 mismatch"))); } *this.buffer = plaintext; diff --git a/crates/rio/src/etag_reader.rs b/crates/rio/src/etag_reader.rs index 77f2de84..e117a1d8 100644 --- a/crates/rio/src/etag_reader.rs +++ b/crates/rio/src/etag_reader.rs @@ -120,7 +120,8 @@ mod tests { let data = b"hello world"; let mut hasher = Md5::new(); hasher.update(data); - let expected = format!("{:x}", hasher.finalize()); + let hex = faster_hex::hex_string(hasher.finalize().as_slice()); + let expected = hex.to_string(); let reader = BufReader::new(&data[..]); let reader = Box::new(WarpReader::new(reader)); let mut etag_reader = EtagReader::new(reader, None); @@ -139,7 +140,8 @@ mod tests { let data = b""; let mut hasher = Md5::new(); hasher.update(data); - let expected = format!("{:x}", hasher.finalize()); + let hex = faster_hex::hex_string(hasher.finalize().as_slice()); + let expected = hex.to_string(); let reader = BufReader::new(&data[..]); let reader = Box::new(WarpReader::new(reader)); let mut etag_reader = EtagReader::new(reader, None); @@ -158,7 +160,8 @@ mod tests { let data = b"abc123"; let mut hasher = Md5::new(); hasher.update(data); - let expected = format!("{:x}", hasher.finalize()); + let hex = faster_hex::hex_string(hasher.finalize().as_slice()); + let expected = hex.to_string(); let reader = BufReader::new(&data[..]); let reader = Box::new(WarpReader::new(reader)); let mut etag_reader = EtagReader::new(reader, None); @@ -195,15 +198,12 @@ mod tests { rand::rng().fill(&mut data[..]); let mut hasher = Md5::new(); hasher.update(&data); - let cloned_data = data.clone(); - - let expected = format!("{:x}", hasher.finalize()); - + let hex = faster_hex::hex_string(hasher.finalize().as_slice()); + let expected = hex.to_string(); let reader = Cursor::new(data.clone()); let reader = Box::new(WarpReader::new(reader)); let mut etag_reader = EtagReader::new(reader, None); - let mut buf = Vec::new(); let n = etag_reader.read_to_end(&mut buf).await.unwrap(); assert_eq!(n, size); diff --git a/crates/rio/src/hash_reader.rs b/crates/rio/src/hash_reader.rs index eb9e773f..15b4a49d 100644 --- a/crates/rio/src/hash_reader.rs +++ b/crates/rio/src/hash_reader.rs @@ -660,7 +660,8 @@ mod tests { let mut hasher = Md5::new(); hasher.update(&data); - let expected = format!("{:x}", hasher.finalize()); + let hex = faster_hex::hex_string(hasher.finalize().as_slice()); + let expected = hex.to_string(); println!("expected: {expected}"); diff --git a/crates/utils/src/crypto.rs b/crates/utils/src/crypto.rs index 720d01cf..9c8bb8b6 100644 --- a/crates/utils/src/crypto.rs +++ b/crates/utils/src/crypto.rs @@ -38,7 +38,7 @@ pub fn is_sha256_checksum(s: &str) -> bool { /// `hmac_sha1(key, data)` pub fn hmac_sha1(key: impl AsRef<[u8]>, data: impl AsRef<[u8]>) -> [u8; 20] { - use hmac::{Hmac, Mac}; + use hmac::{Hmac, KeyInit, Mac}; use sha1::Sha1; let mut m = >::new_from_slice(key.as_ref()).unwrap(); @@ -48,7 +48,7 @@ pub fn hmac_sha1(key: impl AsRef<[u8]>, data: impl AsRef<[u8]>) -> [u8; 20] { /// `hmac_sha256(key, data)` pub fn hmac_sha256(key: impl AsRef<[u8]>, data: impl AsRef<[u8]>) -> [u8; 32] { - use hmac::{Hmac, Mac}; + use hmac::{Hmac, KeyInit, Mac}; use sha2::Sha256; let mut m = Hmac::::new_from_slice(key.as_ref()).unwrap();