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 @@ -39,6 +39,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]',
);

const checksumedMethods = Object.freeze({
completeMultipartUpload: true,
multiObjectDelete: true,
Expand Down Expand Up @@ -81,6 +88,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 @@ -401,6 +409,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 @@ -585,6 +595,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 @@ -597,4 +632,5 @@ module.exports = {
getChecksumDataFromMPUHeaders,
computeCompositeMPUChecksum,
computeFullObjectMPUChecksum,
getCopyObjectChecksumAlgorithm,
};
Loading
Loading