PutObjectPart: set SSE-KMS headers and truncate ETags. (#14578)

This commit fixes two bugs in the `PutObjectPartHandler`.
First, `PutObjectPart` should return SSE-KMS headers
when the object is encrypted using SSE-KMS.
Before, this was not the case.

Second, the ETag should always be a 16 byte hex string,
perhaps followed by a `-X` (where `X` is the number of parts).
However, `PutObjectPart` used to return the encrypted ETag
in case of SSE-KMS. This leaks MinIO internal etag details
through the S3 API.

The combination of both bugs causes clients that use SSE-KMS
to fail when trying to validate the ETag. Since `PutObjectPart`
did not send the SSE-KMS response headers, the response looked
like a plaintext `PutObjectPart` response. Hence, the client
tries to verify that the ETag is the content-md5 of the part.
This could never be the case, since MinIO used to return the
encrypted ETag.

Therefore, clients behaving as specified by the S3 protocol
tried to verify the ETag in a situation they should not.

Signed-off-by: Andreas Auernhammer <hi@aead.dev>
This commit is contained in:
Andreas Auernhammer
2022-03-19 18:15:12 +01:00
committed by GitHub
parent 472c2d828c
commit b0a4beb66a
2 changed files with 80 additions and 70 deletions
+11 -3
View File
@@ -71,11 +71,19 @@ const (
)
// KMSKeyID returns in AWS compatible KMS KeyID() format.
func (o ObjectInfo) KMSKeyID() string {
if len(o.UserDefined) == 0 {
func (o *ObjectInfo) KMSKeyID() string { return kmsKeyIDFromMetadata(o.UserDefined) }
// KMSKeyID returns in AWS compatible KMS KeyID() format.
func (o *MultipartInfo) KMSKeyID() string { return kmsKeyIDFromMetadata(o.UserDefined) }
// kmsKeyIDFromMetadata returns any AWS S3 KMS key ID in the
// metadata, if any. It returns an empty ID if no key ID is
// present.
func kmsKeyIDFromMetadata(metadata map[string]string) string {
if len(metadata) == 0 {
return ""
}
kmsID, ok := o.UserDefined[crypto.MetaKeyID]
kmsID, ok := metadata[crypto.MetaKeyID]
if !ok {
return ""
}