diff --git a/cmd/encryption-v1.go b/cmd/encryption-v1.go index 0dfa2bf81..c3e5604be 100644 --- a/cmd/encryption-v1.go +++ b/cmd/encryption-v1.go @@ -930,26 +930,29 @@ func (o *ObjectInfo) GetDecryptedRange(rs *HTTPRangeSpec) (encOff, encLength, sk } // Assemble slice of (decrypted) part sizes in `sizes` + var sizes []int64 var decObjSize int64 // decrypted total object size - var partSize uint64 - partSize, err = sio.DecryptedSize(uint64(o.Size)) - if err != nil { - return - } - sizes := []int64{int64(partSize)} - decObjSize = sizes[0] if isEncryptedMultipart(*o) { sizes = make([]int64, len(o.Parts)) - decObjSize = 0 for i, part := range o.Parts { + var partSize uint64 partSize, err = sio.DecryptedSize(uint64(part.Size)) if err != nil { + err = errObjectTampered return } - t := int64(partSize) - sizes[i] = t - decObjSize += t + sizes[i] = int64(partSize) + decObjSize += int64(partSize) + } + } else { + var partSize uint64 + partSize, err = sio.DecryptedSize(uint64(o.Size)) + if err != nil { + err = errObjectTampered + return } + sizes = []int64{int64(partSize)} + decObjSize = sizes[0] } var off, length int64 diff --git a/cmd/encryption-v1_test.go b/cmd/encryption-v1_test.go index f2af329f6..9cd4221d7 100644 --- a/cmd/encryption-v1_test.go +++ b/cmd/encryption-v1_test.go @@ -334,6 +334,66 @@ func TestDecryptObjectInfo(t *testing.T) { } } +// Tests for issue reproduced when getting the right encrypted +// offset of the object. +func TestGetDecryptedRange_Issue50(t *testing.T) { + rs, err := parseRequestRangeSpec("bytes=594870256-594870263") + if err != nil { + t.Fatal(err) + } + + objInfo := ObjectInfo{ + Bucket: "bucket", + Name: "object", + Size: 595160760, + UserDefined: map[string]string{ + crypto.SSEMultipart: "", + crypto.SSEIV: "HTexa=", + crypto.SSESealAlgorithm: "DAREv2-HMAC-SHA256", + crypto.SSECSealedKey: "IAA8PGAA==", + ReservedMetadataPrefix + "actual-size": "594870264", + "content-type": "application/octet-stream", + "etag": "166b1545b4c1535294ee0686678bea8c-2", + }, + Parts: []objectPartInfo{ + { + Number: 1, + Name: "part.1", + ETag: "etag1", + Size: 297580380, + ActualSize: 297435132, + }, + { + Number: 2, + Name: "part.2", + ETag: "etag2", + Size: 297580380, + ActualSize: 297435132, + }, + }, + } + + encOff, encLength, skipLen, seqNumber, partStart, err := objInfo.GetDecryptedRange(rs) + if err != nil { + t.Fatalf("Test: failed %s", err) + } + if encOff != 595127964 { + t.Fatalf("Test: expected %d, got %d", 595127964, encOff) + } + if encLength != 32796 { + t.Fatalf("Test: expected %d, got %d", 32796, encLength) + } + if skipLen != 32756 { + t.Fatalf("Test: expected %d, got %d", 32756, skipLen) + } + if seqNumber != 4538 { + t.Fatalf("Test: expected %d, got %d", 4538, seqNumber) + } + if partStart != 1 { + t.Fatalf("Test: expected %d, got %d", 1, partStart) + } +} + func TestGetDecryptedRange(t *testing.T) { var ( pkgSz = int64(64) * humanize.KiByte