fix: authenticate SSE-C keys on zero-byte reads

Unseal supplied SSE-C and copy-source keys after range and request preconditions when a zero-byte read cannot build a decryptor. Preserve internal no-decryption, replication, restore, and absent-header reads.

Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-08-29 17:26:09 +08:00
parent 5732930102
commit b73581b05d
3 changed files with 256 additions and 2 deletions
+18
View File
@@ -574,6 +574,24 @@ func DecryptCopyRequestR(client io.Reader, h http.Header, bucket, object string,
return newDecryptReader(client, key, bucket, object, seqNumber, metadata)
}
// checkSSECReadKey authenticates a supplied SSE-C read key against the sealed
// object key when a read has no data from which to build a decryptor.
func checkSSECReadKey(h http.Header, oi ObjectInfo, opts ObjectOptions) error {
if opts.NoDecryption || opts.Transition.RestoreRequest != nil || !crypto.SSEC.IsEncrypted(oi.UserDefined) {
return nil
}
switch {
case crypto.SSECopy.IsRequested(h):
_, err := crypto.SSECopy.UnsealObjectKey(h, oi.UserDefined, oi.Bucket, oi.Name)
return err
case crypto.SSEC.IsRequested(h):
_, err := crypto.SSEC.UnsealObjectKey(h, oi.UserDefined, oi.Bucket, oi.Name)
return err
default:
return nil
}
}
func newDecryptReader(client io.Reader, key []byte, bucket, object string, seqNumber uint32, metadata map[string]string) (io.Reader, error) {
objectEncryptionKey, err := decryptObjectMeta(key, bucket, object, metadata)
if err != nil {