fix: Fixes the signed chunk trailer encoding to return proper api errors for invalid and incorrect checksums.

Fixes #1165

The signed chunk encoding with trailers should return api error for:

1. Invalid checksum - `(InvalidRequest) Value for x-amz-checksum-x trailing header is invalid.`
2. Incorrect checksum - `(BadDigest) The x you specified did not match the calculated checksum.`

Where `x` could be crc32, crc32c, sha1 ...
This commit is contained in:
niksis02
2025-03-29 01:46:45 +04:00
parent d47dc72abf
commit 7d4076b944
2 changed files with 18 additions and 2 deletions

View File

@@ -30,6 +30,7 @@ import (
"strings"
"time"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/versity/versitygw/s3err"
)
@@ -190,7 +191,8 @@ func (cr *ChunkReader) verifyChecksum() error {
checksumHash := cr.checksumHash.Sum(nil)
checksum := base64.StdEncoding.EncodeToString(checksumHash)
if checksum != cr.parsedChecksum {
return fmt.Errorf("actual checksum: %v, expected checksum: %v", checksum, cr.parsedChecksum)
algo := types.ChecksumAlgorithm(strings.ToUpper(strings.TrimPrefix(string(cr.trailer), "x-amz-checksum-")))
return s3err.GetChecksumBadDigestErr(algo)
}
return nil
@@ -380,12 +382,18 @@ func (cr *ChunkReader) parseChunkHeaderBytes(header []byte, l *int) (int64, stri
return 0, "", 0, errInvalidChunkFormat
}
algo := types.ChecksumAlgorithm(strings.ToUpper(strings.TrimPrefix(trailer, "x-amz-checksum-")))
// parse the checksum
checksum, err := readAndTrim(rdr, '\r')
if err != nil {
return cr.handleRdrErr(err, header)
}
if !IsValidChecksum(checksum, algo) {
return 0, "", 0, s3err.GetInvalidTrailingChecksumHeaderErr(trailer)
}
err = readAndSkip(rdr, '\n')
if err != nil {
return cr.handleRdrErr(err, header)

View File

@@ -770,6 +770,14 @@ func GetInvalidChecksumHeaderErr(header string) APIError {
}
}
func GetInvalidTrailingChecksumHeaderErr(header string) APIError {
return APIError{
Code: "InvalidRequest",
Description: fmt.Sprintf("Value for %v trailing header is invalid.", header),
HTTPStatusCode: http.StatusBadRequest,
}
}
// Returns checksum type mismatch APIError
func GetChecksumTypeMismatchErr(expected, actual types.ChecksumAlgorithm) APIError {
return APIError{
@@ -783,7 +791,7 @@ func GetChecksumTypeMismatchErr(expected, actual types.ChecksumAlgorithm) APIErr
func GetChecksumBadDigestErr(algo types.ChecksumAlgorithm) APIError {
return APIError{
Code: "BadDigest",
Description: fmt.Sprintf("The %v you specified did not match the calculated checksum.", strings.ToLower(string(algo))),
Description: fmt.Sprintf("The %v you specified did not match the calculated checksum.", algo),
HTTPStatusCode: http.StatusBadRequest,
}
}