🔒 Upgrade Cryptography Libraries to Latest RC Versions (#837)

* fix

* chore: upgrade cryptography libraries to RC versions

- Upgrade aes-gcm to 0.11.0-rc.2 with rand_core support
- Upgrade chacha20poly1305 to 0.11.0-rc.2
- Upgrade argon2 to 0.6.0-rc.2 with std features
- Upgrade hmac to 0.13.0-rc.3
- Upgrade pbkdf2 to 0.13.0-rc.2
- Upgrade rsa to 0.10.0-rc.10
- Upgrade sha1 and sha2 to 0.11.0-rc.3
- Upgrade md-5 to 0.11.0-rc.3

These upgrades provide enhanced security features and performance
improvements while maintaining backward compatibility with existing
encryption workflows.

* add

* improve code

* fix
This commit is contained in:
houseme
2025-11-11 21:10:03 +08:00
committed by GitHub
parent 8a020ec4d9
commit 7e1a9e2ede
20 changed files with 484 additions and 313 deletions

420
Cargo.lock generated
View File

@@ -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",

View File

@@ -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"

View File

@@ -29,6 +29,7 @@ base64-simd = { workspace = true }
rsa = { workspace = true }
serde.workspace = true
serde_json.workspace = true
rand.workspace = true
[lints]
workspace = true

View File

@@ -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<String> {
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();

View File

@@ -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 }

View File

@@ -19,127 +19,37 @@ pub fn decrypt_data(password: &[u8], data: &[u8]) -> Result<Vec<u8>, 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<R: Read>(password: &str, mut data: R) -> Result<Vec<u8>, 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::<Sha256>(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<T: aes_gcm::aead::Aead>(stream: T, nonce: &[u8], data: &[u8]) -> Result<Vec<u8>, 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<u8, <T as AeadCore>::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")))]

View File

@@ -43,7 +43,7 @@ pub fn encrypt_data(password: &[u8], data: &[u8]) -> Result<Vec<u8>, 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<T: aes_gcm::aead::Aead>(
data: &[u8],
) -> Result<Vec<u8>, 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<u8, <T as AeadCore>::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)

View File

@@ -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 }

View File

@@ -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::<i64>().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<String, Error> {
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)
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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::<Aes256Gcm>::from_slice(&hash))
let key = Key::<Aes256Gcm>::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<MasterKey> {
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<u8> {
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<u8>, Vec<u8>)> {
// Load the actual master key material
let key_material = self.get_key_material(key_id).await?;
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(&key_material));
let key = Key::<Aes256Gcm>::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<Vec<u8>> {
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::<Aes256Gcm>::from_slice(&key_material));
let key = Key::<Aes256Gcm>::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

View File

@@ -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

View File

@@ -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::<Aes256Gcm>::from_slice(key);
let cipher = Aes256Gcm::new(key);
let key = Key::<Aes256Gcm>::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<u8> {
};
let mut iv = vec![0u8; iv_size];
OsRng.fill_bytes(&mut iv);
rand::rng().fill(&mut iv[..]);
iv
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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}");

View File

@@ -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 = <Hmac<Sha1>>::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::<Sha256>::new_from_slice(key.as_ref()).unwrap();