mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-25 21:46:50 +00:00
refactor(sse): keep one bucket-default algorithm mapping for every writer (#6251)
This commit is contained in:
@@ -97,7 +97,7 @@ use super::storage_api::object_usecase::set_disk::{
|
|||||||
};
|
};
|
||||||
use super::storage_api::object_usecase::sse::{
|
use super::storage_api::object_usecase::sse::{
|
||||||
DecryptionRequest, EncryptionRequest, SSEType, SseKmsPrincipal, apply_bucket_default_lock_retention,
|
DecryptionRequest, EncryptionRequest, SSEType, SseKmsPrincipal, apply_bucket_default_lock_retention,
|
||||||
authorize_sse_kms_object_read, build_ssec_read_headers, encryption_material_to_metadata,
|
authorize_sse_kms_object_read, bucket_default_write_sse, build_ssec_read_headers, encryption_material_to_metadata,
|
||||||
extract_server_side_encryption_from_headers, extract_ssec_params_from_headers, extract_ssekms_context_from_headers,
|
extract_server_side_encryption_from_headers, extract_ssec_params_from_headers, extract_ssekms_context_from_headers,
|
||||||
get_buffer_size_opt_in, load_bucket_object_lock_config_state, map_get_object_reader_error, sse_decryption, sse_encryption,
|
get_buffer_size_opt_in, load_bucket_object_lock_config_state, map_get_object_reader_error, sse_decryption, sse_encryption,
|
||||||
validate_bucket_object_lock_enabled_state,
|
validate_bucket_object_lock_enabled_state,
|
||||||
@@ -169,8 +169,8 @@ use s3s::dto::{
|
|||||||
ObjectLockLegalHoldStatus, ObjectLockMode, ObjectLockRetention, ObjectLockRetentionMode, ObjectPart, PutObjectInput,
|
ObjectLockLegalHoldStatus, ObjectLockMode, ObjectLockRetention, ObjectLockRetentionMode, ObjectPart, PutObjectInput,
|
||||||
PutObjectOutput, Range, RequestCharged, RestoreObjectInput, RestoreObjectOutput, RestoreStatus, SSECustomerAlgorithm,
|
PutObjectOutput, Range, RequestCharged, RestoreObjectInput, RestoreObjectOutput, RestoreStatus, SSECustomerAlgorithm,
|
||||||
SSECustomerKeyMD5, SSEKMSKeyId, SelectObjectContentInput, SelectObjectContentOutput, ServerSideEncryption,
|
SSECustomerKeyMD5, SSEKMSKeyId, SelectObjectContentInput, SelectObjectContentOutput, ServerSideEncryption,
|
||||||
ServerSideEncryptionByDefault, ServerSideEncryptionConfiguration, StorageClass, StreamingBlob, TaggingDirective,
|
ServerSideEncryptionConfiguration, StorageClass, StreamingBlob, TaggingDirective, TaggingHeader, Timestamp, TimestampFormat,
|
||||||
TaggingHeader, Timestamp, TimestampFormat, WebsiteRedirectLocation,
|
WebsiteRedirectLocation,
|
||||||
};
|
};
|
||||||
use s3s::header::{X_AMZ_RESTORE, X_AMZ_RESTORE_OUTPUT_PATH};
|
use s3s::header::{X_AMZ_RESTORE, X_AMZ_RESTORE_OUTPUT_PATH};
|
||||||
use s3s::stream::{ByteStream, DynByteStream, RemainingLength};
|
use s3s::stream::{ByteStream, DynByteStream, RemainingLength};
|
||||||
@@ -2676,25 +2676,6 @@ fn has_put_sse_request_headers(headers: &HeaderMap) -> bool {
|
|||||||
|| headers.get(AMZ_SERVER_SIDE_ENCRYPTION_KMS_ID).is_some()
|
|| headers.get(AMZ_SERVER_SIDE_ENCRYPTION_KMS_ID).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Managed SSE resolved from a bucket default encryption rule on the copy path.
|
|
||||||
///
|
|
||||||
/// Unknown algorithms fall back to AES256, the same total mapping as the PUT and
|
|
||||||
/// extract paths and the storage-layer resolver (`prepare_sse_configuration`), which
|
|
||||||
/// `sse_encryption` re-runs when it mints the destination DEK. Resolving `None` here
|
|
||||||
/// instead lets a same-name copy under a malformed bucket default pass the
|
|
||||||
/// `copy_changes_encryption` guard and take the metadata-only shortcut while the
|
|
||||||
/// storage layer still encrypts: fresh DEK metadata is committed beside the untouched
|
|
||||||
/// plaintext blocks and the object becomes unreadable. Reachable only via corrupt or
|
|
||||||
/// hand-edited bucket metadata — PutBucketEncryption rejects unknown algorithms
|
|
||||||
/// (backlog#1826).
|
|
||||||
fn bucket_default_write_sse(sse: &ServerSideEncryptionByDefault) -> ServerSideEncryption {
|
|
||||||
match sse.sse_algorithm.as_str() {
|
|
||||||
"AES256" => ServerSideEncryption::from_static(ServerSideEncryption::AES256),
|
|
||||||
"aws:kms" => ServerSideEncryption::from_static(ServerSideEncryption::AWS_KMS),
|
|
||||||
_ => ServerSideEncryption::from_static(ServerSideEncryption::AES256),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolve the effective server-side encryption for a write against the bucket's
|
/// Resolve the effective server-side encryption for a write against the bucket's
|
||||||
/// default encryption configuration.
|
/// default encryption configuration.
|
||||||
///
|
///
|
||||||
@@ -10115,8 +10096,8 @@ mod tests {
|
|||||||
DefaultRetention, Delete, DeleteMarkerReplication, DeleteMarkerReplicationStatus, DeleteReplication,
|
DefaultRetention, Delete, DeleteMarkerReplication, DeleteMarkerReplicationStatus, DeleteReplication,
|
||||||
DeleteReplicationStatus, Destination, ExistingObjectReplication, ExistingObjectReplicationStatus, ObjectIdentifier,
|
DeleteReplicationStatus, Destination, ExistingObjectReplication, ExistingObjectReplicationStatus, ObjectIdentifier,
|
||||||
ObjectLockConfiguration, ObjectLockEnabled, ObjectLockRule, ReplicaModifications, ReplicaModificationsStatus,
|
ObjectLockConfiguration, ObjectLockEnabled, ObjectLockRule, ReplicaModifications, ReplicaModificationsStatus,
|
||||||
ReplicationConfiguration, ReplicationRule, ReplicationRuleStatus, RestoreRequest, ServerSideEncryptionConfiguration,
|
ReplicationConfiguration, ReplicationRule, ReplicationRuleStatus, RestoreRequest, ServerSideEncryptionByDefault,
|
||||||
ServerSideEncryptionRule, SourceSelectionCriteria,
|
ServerSideEncryptionConfiguration, ServerSideEncryptionRule, SourceSelectionCriteria,
|
||||||
};
|
};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|||||||
@@ -1032,8 +1032,9 @@ pub(crate) mod sse {
|
|||||||
validate_bucket_object_lock_enabled_state,
|
validate_bucket_object_lock_enabled_state,
|
||||||
};
|
};
|
||||||
pub(crate) use crate::storage::storage_api::sse_consumer::{
|
pub(crate) use crate::storage::storage_api::sse_consumer::{
|
||||||
EncryptionKeyKind, SSEType, build_ssec_read_headers, encryption_material_to_metadata, extract_ssec_params_from_headers,
|
EncryptionKeyKind, SSEType, bucket_default_write_sse, build_ssec_read_headers, encryption_material_to_metadata,
|
||||||
extract_ssekms_context_from_headers, map_get_object_reader_error, mark_encrypted_multipart_metadata,
|
extract_ssec_params_from_headers, extract_ssekms_context_from_headers, map_get_object_reader_error,
|
||||||
|
mark_encrypted_multipart_metadata,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ use rustfs_utils::http::headers::{
|
|||||||
AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY_MD5, AMZ_SERVER_SIDE_ENCRYPTION_KMS_CONTEXT,
|
AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY_MD5, AMZ_SERVER_SIDE_ENCRYPTION_KMS_CONTEXT,
|
||||||
};
|
};
|
||||||
use rustfs_utils::path::path_join_buf;
|
use rustfs_utils::path::path_join_buf;
|
||||||
use s3s::dto::{SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5, SSEKMSKeyId};
|
use s3s::dto::{SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5, SSEKMSKeyId, ServerSideEncryptionByDefault};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -203,6 +203,24 @@ pub struct SseConfiguration {
|
|||||||
/// Effective KMS key ID (after considering bucket defaults)
|
/// Effective KMS key ID (after considering bucket defaults)
|
||||||
pub effective_kms_key_id: Option<SSEKMSKeyId>,
|
pub effective_kms_key_id: Option<SSEKMSKeyId>,
|
||||||
}
|
}
|
||||||
|
/// Managed SSE resolved from a bucket default encryption rule on a write path.
|
||||||
|
///
|
||||||
|
/// The single mapping shared by every writer: this resolver, and the PUT, COPY
|
||||||
|
/// and extract paths in `app::object_usecase`, which reach it through
|
||||||
|
/// `resolve_bucket_default_sse`. Unknown algorithms fall back to AES256 rather
|
||||||
|
/// than to `None`. Resolving `None` instead lets a same-name copy under a
|
||||||
|
/// malformed bucket default pass the `copy_changes_encryption` guard and take
|
||||||
|
/// the metadata-only shortcut while this layer still encrypts: fresh DEK
|
||||||
|
/// metadata is committed beside the untouched plaintext blocks and the object
|
||||||
|
/// becomes unreadable. Reachable only via corrupt or hand-edited bucket
|
||||||
|
/// metadata — PutBucketEncryption rejects unknown algorithms (backlog#1826).
|
||||||
|
pub(crate) fn bucket_default_write_sse(sse: &ServerSideEncryptionByDefault) -> ServerSideEncryption {
|
||||||
|
match sse.sse_algorithm.as_str() {
|
||||||
|
"AES256" => ServerSideEncryption::from_static(ServerSideEncryption::AES256),
|
||||||
|
"aws:kms" => ServerSideEncryption::from_static(ServerSideEncryption::AWS_KMS),
|
||||||
|
_ => ServerSideEncryption::from_static(ServerSideEncryption::AES256),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Prepare SSE configuration by resolving request parameters with bucket defaults
|
/// Prepare SSE configuration by resolving request parameters with bucket defaults
|
||||||
///
|
///
|
||||||
@@ -266,11 +284,7 @@ async fn prepare_sse_configuration(
|
|||||||
has_kms_key_id = sse.kms_master_key_id.is_some(),
|
has_kms_key_id = sse.kms_master_key_id.is_some(),
|
||||||
"Bucket SSE default resolved"
|
"Bucket SSE default resolved"
|
||||||
);
|
);
|
||||||
match sse.sse_algorithm.as_str() {
|
bucket_default_write_sse(sse)
|
||||||
"AES256" => ServerSideEncryption::from_static(ServerSideEncryption::AES256),
|
|
||||||
"aws:kms" => ServerSideEncryption::from_static(ServerSideEncryption::AWS_KMS),
|
|
||||||
_ => ServerSideEncryption::from_static(ServerSideEncryption::AES256), // fallback
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -344,9 +344,9 @@ pub(crate) mod s3_api_consumer {
|
|||||||
|
|
||||||
pub(crate) mod sse_consumer {
|
pub(crate) mod sse_consumer {
|
||||||
pub(crate) use super::super::sse::{
|
pub(crate) use super::super::sse::{
|
||||||
EncryptionKeyKind, SSEType, build_ssec_read_headers, encryption_material_to_metadata, extract_ssec_params_from_headers,
|
EncryptionKeyKind, SSEType, bucket_default_write_sse, build_ssec_read_headers, encryption_material_to_metadata,
|
||||||
extract_ssekms_context_from_headers, log_sse_kms_key_policy_mode, map_get_object_reader_error,
|
extract_ssec_params_from_headers, extract_ssekms_context_from_headers, log_sse_kms_key_policy_mode,
|
||||||
mark_encrypted_multipart_metadata,
|
map_get_object_reader_error, mark_encrypted_multipart_metadata,
|
||||||
};
|
};
|
||||||
pub(crate) use super::{
|
pub(crate) use super::{
|
||||||
DecryptionRequest, EncryptionRequest, PrepareEncryptionRequest, SseKmsPrincipal, apply_bucket_default_lock_retention,
|
DecryptionRequest, EncryptionRequest, PrepareEncryptionRequest, SseKmsPrincipal, apply_bucket_default_lock_retention,
|
||||||
|
|||||||
Reference in New Issue
Block a user