mirror of
https://github.com/pgsty/minio.git
synced 2026-07-25 23:16:16 +03:00
etag: fix incorrect multipart detection (#14631)
This commit fixes a subtle bug in the ETag `IsEncrypted` implementation. An encrypted ETag may contain random bytes, i.e. some randomness used for encryption. This random value can contain a '-' byte simple due to being randomly generated. Before, the `IsEncrypted` implementation incorrectly assumed that an encrypted ETag cannot contain a '-' since it would be a multipart ETag. Multipart ETags have a 16 byte value followed by a '-' and the part number. For example: ``` 059ba80b807c3c776fb3bcf3f33e11ae-2 ``` However, the following encrypted ETag ``` 20000f00db2d90a7b40782d4cff2b41a7799fc1e7ead25972db65150118dfbe2ba76a3c002da28f85c840cd2001a28a9 ``` also contains a '-' byte but is not a multipart ETag. This commit fixes the `IsEncrypted` implementation simply by checking whether the ETag is at least 32 bytes long. A valid multipart ETag is never 32 bytes long since a part number must be <= 10000. However, an encrypted ETag must be at least 32 bytes long. It contains the encrypted ETag bytes (16 bytes) and the authentication tag added by the AEAD cipher (again 16 bytes). Signed-off-by: Andreas Auernhammer <hi@aead.dev>
This commit is contained in:
committed by
GitHub
parent
5cfedcfe33
commit
062f3ea43a
+17
-2
@@ -143,7 +143,22 @@ func (e ETag) String() string {
|
||||
|
||||
// IsEncrypted reports whether the ETag is encrypted.
|
||||
func (e ETag) IsEncrypted() bool {
|
||||
return len(e) > 16 && !bytes.ContainsRune(e, '-')
|
||||
// An encrypted ETag must be at least 32 bytes long.
|
||||
// It contains the encrypted ETag value + an authentication
|
||||
// code generated by the AEAD cipher.
|
||||
//
|
||||
// Here is an incorrect implementation of IsEncrypted:
|
||||
//
|
||||
// return len(e) > 16 && !bytes.ContainsRune(e, '-')
|
||||
//
|
||||
// An encrypted ETag may contain some random bytes - e.g.
|
||||
// and nonce value. This nonce value may contain a '-'
|
||||
// just by its nature of being randomly generated.
|
||||
// The above implementation would incorrectly consider
|
||||
// such an ETag (with a nonce value containing a '-')
|
||||
// as non-encrypted.
|
||||
|
||||
return len(e) >= 32 // We consider all ETags longer than 32 bytes as encrypted
|
||||
}
|
||||
|
||||
// IsMultipart reports whether the ETag belongs to an
|
||||
@@ -151,7 +166,7 @@ func (e ETag) IsEncrypted() bool {
|
||||
// API.
|
||||
// An S3 multipart ETag has a -<part-number> suffix.
|
||||
func (e ETag) IsMultipart() bool {
|
||||
return len(e) > 16 && bytes.ContainsRune(e, '-')
|
||||
return len(e) > 16 && !e.IsEncrypted() && bytes.ContainsRune(e, '-')
|
||||
}
|
||||
|
||||
// Parts returns the number of object parts that are
|
||||
|
||||
Reference in New Issue
Block a user