Skip to content
36 changes: 36 additions & 0 deletions lib/api/apiUtils/integrity/validateChecksums.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ const errMPUTypeWithoutAlgo = errorInstances.InvalidRequest.customizeDescription
'The x-amz-checksum-type header can only be used with the x-amz-checksum-algorithm header.',
);

// TODO(S3C-11278): Update with 'MD5', 'SHA512', 'XXHASH128', 'XXHASH3', 'XXHASH64' when they are introduced.
// https://scality.atlassian.net/browse/S3C-11278
const errCopyChecksumAlgoNotSupported = errorInstances.InvalidRequest.customizeDescription(
'Checksum algorithm provided is unsupported. Please try again with any of the valid types: ' +
'[CRC32, CRC32C, CRC64NVME, SHA1, SHA256]',
);

// Methods that validate BOTH Content-MD5 and x-amz-checksum-* against the
// buffered request body. For these, x-amz-checksum-* is the body digest.
const checksumedMethods = Object.freeze({
Expand Down Expand Up @@ -90,6 +97,7 @@ const ChecksumError = Object.freeze({
MPUTypeInvalid: 'MPUTypeInvalid',
MPUTypeWithoutAlgo: 'MPUTypeWithoutAlgo',
MPUInvalidCombination: 'MPUInvalidCombination',
CopyChecksumAlgoNotSupported: 'CopyChecksumAlgoNotSupported',
});

const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
Expand Down Expand Up @@ -438,6 +446,8 @@ function arsenalErrorFromChecksumError(err) {
`The ${err.details.type} checksum type cannot be used ` +
`with the ${err.details.algorithm.toUpperCase()} checksum algorithm.`,
);
case ChecksumError.CopyChecksumAlgoNotSupported:
return errCopyChecksumAlgoNotSupported;
default:
return ArsenalErrors.BadDigest;
}
Expand Down Expand Up @@ -699,6 +709,31 @@ function computeFullObjectMPUChecksum(algorithm, parts) {
return { checksum: combinePartCrcs(parts, params.polyReversed, params.dim), error: null };
}

/**
* Read and validate the x-amz-checksum-algorithm header for CopyObject.
*
* @param {object} headers - request headers
* @returns {{ error: null, algorithm: string|null }
* | { error: { error: string, details: { algorithm: string } }, algorithm: null }}
*/
function getCopyObjectChecksumAlgorithm(headers) {
const requested = headers['x-amz-checksum-algorithm'];
if (requested === undefined) {
return { error: null, algorithm: null };
}
const algorithm = requested.toLowerCase();
if (!algorithms[algorithm]) {
return {
error: {
error: ChecksumError.CopyChecksumAlgoNotSupported,
details: { algorithm: requested },
},
algorithm: null,
};
}
return { error: null, algorithm };
}

module.exports = {
ChecksumError,
defaultChecksumData,
Expand All @@ -712,4 +747,5 @@ module.exports = {
computeCompositeMPUChecksum,
computeFullObjectMPUChecksum,
validateCompleteMultipartUploadChecksum,
getCopyObjectChecksumAlgorithm,
};
Loading
Loading