Merge pull request #1173 from versity/sis/sign-chunk-encoding-trailer-checksum-validation

fix: Fixes the signed chunk trailer encoding to return proper api errors for invalid and incorrect checksums.
This commit is contained in:
Ben McClelland
2025-03-29 16:49:25 -07:00
committed by GitHub
3 changed files with 19 additions and 7 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,
}
}

View File

@@ -361,11 +361,7 @@ check_checksum_rest_incorrect() {
log 2 "error setting up bucket and file"
return 1
fi
if [ "$DIRECT" == "true" ]; then
error_cs_str="$(echo "$1" | tr '[:lower:]' '[:upper:]')"
else
error_cs_str="$1"
fi
error_cs_str="$(echo "$1" | tr '[:lower:]' '[:upper:]')"
error_message="The $error_cs_str you specified did not match the calculated checksum."
if ! calculate_incorrect_checksum "$1" "$(cat "$TEST_FILE_FOLDER/$test_file")"; then
log 2 "error calculating incorrect checksum"