fix(storage): restore legacy SSE-S3 read compatibility (#3584)

* Update .gitignore

* Fix. fixed SSE-S3 compatibility issues in large-scale testing

* fix

* fix(ecstore): reject whitespace bucket names

* Update replication_extension_test.rs

* style(ecstore): format bucket whitespace test

---------

Co-authored-by: houseme <housemecn@gmail.com>
Co-authored-by: cxymds <cxymds@gmail.com>
This commit is contained in:
唐小鸭
2026-06-23 21:35:17 +08:00
committed by GitHub
parent 5c60f0cae9
commit eff656e086
13 changed files with 1239 additions and 11 deletions
+36 -3
View File
@@ -97,6 +97,14 @@ fn build_object_encryption_context(
object_context
}
#[cfg(feature = "rio-v2")]
fn is_legacy_rustfs_managed_metadata(metadata: &HashMap<String, String>) -> bool {
metadata_get(metadata, INTERNAL_ENCRYPTION_KEY_HEADER).is_some()
&& metadata_get(metadata, INTERNAL_ENCRYPTION_IV_HEADER).is_some()
&& metadata_get(metadata, MINIO_INTERNAL_ENCRYPTION_S3_SEALED_KEY_HEADER).is_none()
&& metadata_get(metadata, MINIO_INTERNAL_ENCRYPTION_KMS_SEALED_KEY_HEADER).is_none()
}
fn part_plaintext_size(part: &ObjectPartInfo) -> i64 {
if part.actual_size > 0 {
part.actual_size
@@ -1301,9 +1309,16 @@ async fn resolve_managed_material(bucket: &str, object: &str, metadata: &HashMap
let object_context = build_object_encryption_context(bucket, object, kms_context.as_ref());
let decrypted_key = if let Some(service) = get_global_encryption_service().await {
service
.decrypt_data_key(&encrypted_dek, &object_context)
.await
#[cfg(feature = "rio-v2")]
let data_key = if is_legacy_rustfs_managed_metadata(&normalized_metadata) {
service.decrypt_legacy_data_key(&encrypted_dek).await
} else {
service.decrypt_data_key(&encrypted_dek, &object_context).await
};
#[cfg(not(feature = "rio-v2"))]
let data_key = service.decrypt_data_key(&encrypted_dek, &object_context).await;
data_key
.map_err(|e| Error::other(format!("failed to decrypt managed data key: {e}")))?
.plaintext_key
} else {
@@ -1601,6 +1616,24 @@ mod tests {
headers
}
#[cfg(feature = "rio-v2")]
#[test]
fn test_legacy_managed_metadata_excludes_sealed_keys() {
let legacy_metadata = HashMap::from([
(INTERNAL_ENCRYPTION_KEY_HEADER.to_string(), "encrypted-dek".to_string()),
(INTERNAL_ENCRYPTION_IV_HEADER.to_string(), "nonce".to_string()),
]);
assert!(is_legacy_rustfs_managed_metadata(&legacy_metadata));
let sealed_metadata = HashMap::from([
(INTERNAL_ENCRYPTION_KEY_HEADER.to_string(), "encrypted-dek".to_string()),
(INTERNAL_ENCRYPTION_IV_HEADER.to_string(), "nonce".to_string()),
(MINIO_INTERNAL_ENCRYPTION_S3_SEALED_KEY_HEADER.to_string(), "sealed-key".to_string()),
]);
assert!(!is_legacy_rustfs_managed_metadata(&sealed_metadata));
}
#[cfg(feature = "rio-v2")]
fn seal_ssec_object_key_for_test(
bucket: &str,