Merge forward #2902 (Add checksum sanity validation on template registration)

This commit is contained in:
Rafael Weingärtner 2018-10-16 10:25:50 -03:00
commit 92f8cda64a
3 changed files with 58 additions and 2 deletions

View File

@ -39,6 +39,7 @@ import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplat
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
import org.apache.cloudstack.utils.security.DigestHelper;
import org.apache.log4j.Logger;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
@ -155,6 +156,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
String url = profile.getUrl();
UriUtils.validateUrl(ImageFormat.ISO.getFileExtension(), url);
if (cmd.isDirectDownload()) {
DigestHelper.validateChecksumString(cmd.getChecksum());
Long templateSize = performDirectDownloadUrlValidation(url);
profile.setSize(templateSize);
}
@ -170,6 +172,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
String url = profile.getUrl();
UriUtils.validateUrl(cmd.getFormat(), url);
if (cmd.isDirectDownload()) {
DigestHelper.validateChecksumString(cmd.getChecksum());
Long templateSize = performDirectDownloadUrlValidation(url);
profile.setSize(templateSize);
}

View File

@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.utils.security;
import org.apache.commons.lang.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
@ -70,9 +72,9 @@ public class DigestHelper {
return checksum;
}
static final Map<String, Integer> paddingLengths = creatPaddingLengths();
static final Map<String, Integer> paddingLengths = getChecksumLengthsMap();
private static final Map<String, Integer> creatPaddingLengths() {
private static final Map<String, Integer> getChecksumLengthsMap() {
Map<String, Integer> map = new HashMap<>();
map.put("MD5", 32);
map.put("SHA-1", 40);
@ -93,4 +95,25 @@ public class DigestHelper {
}
return true;
}
/**
* Checksum sanity for not empty checksum. Expected format: {ALG}HASH
* If ALG is missing, MD5 is assumed as default
* Hash length is verified, depending on the algorithm.
* IllegalArgumentException is thrown in case of malformed checksums
*/
public static void validateChecksumString(String checksum) {
if(StringUtils.isNotEmpty(checksum)) {
ChecksumValue checksumValue = new ChecksumValue(checksum);
String digest = checksumValue.getChecksum();
Map<String, Integer> map = getChecksumLengthsMap();
if (!map.containsKey(checksumValue.getAlgorithm())) {
throw new IllegalArgumentException("Algorithm " + checksumValue.getAlgorithm() + " was provided but it is not one of the supported algorithms");
}
Integer expectedLength = map.get(checksumValue.getAlgorithm());
if (digest.length() != expectedLength) {
throw new IllegalArgumentException("Checksum digest length should be " + expectedLength + " instead of " + digest.length());
}
}
}
}

View File

@ -32,8 +32,10 @@ public class DigestHelperTest {
private final static String INPUT_STRING_NO2 = "01234567890123456789012345678901234567890123456789012345678901234567890123456789b\n";
private final static String INPUT_STRING_NO3 = "01234567890123456789012345678901234567890123456789012345678901234567890123456789h\n";
private final static String SHA256_CHECKSUM = "{SHA-256}c6ab15af7842d23d3c06c138b53a7d09c5e351a79c4eb3c8ca8d65e5ce8900ab";
private final static String SHA256_NO_PREFIX_CHECKSUM = "c6ab15af7842d23d3c06c138b53a7d09c5e351a79c4eb3c8ca8d65e5ce8900ab";
private final static String SHA1_CHECKSUM = "{SHA-1}49e4b2f4292b63e88597c127d11bc2cc0f2ca0ff";
private final static String MD5_CHECKSUM = "{MD5}d141a8eeaf6bba779d1d1dc5102a81c5";
private final static String MD5_NO_PREFIX_CHECKSUM = "d141a8eeaf6bba779d1d1dc5102a81c5";
private final static String ZERO_PADDED_MD5_CHECKSUM = "{MD5}0e51dfa74b87f19dd5e0124d6a2195e3";
private final static String ZERO_PADDED_SHA256_CHECKSUM = "{SHA-256}08b5ae0c7d7d45d8ed406d7c3c7da695b81187903694314d97f8a37752a6b241";
private static final String MD5 = "MD5";
@ -97,6 +99,34 @@ public class DigestHelperTest {
public void reset() throws IOException {
inputStream.reset();
}
@Test(expected = IllegalArgumentException.class)
public void testChecksumSanityNoPrefixWrongAlgorithm() {
DigestHelper.validateChecksumString(SHA256_NO_PREFIX_CHECKSUM);
}
@Test
public void testChecksumSanityNoPrefix() {
DigestHelper.validateChecksumString(MD5_NO_PREFIX_CHECKSUM);
}
@Test
public void testChecksumSanityPrefixEmptyAlgorithm() {
String checksum = "{}" + MD5_NO_PREFIX_CHECKSUM;
DigestHelper.validateChecksumString(checksum);
}
@Test(expected = IllegalArgumentException.class)
public void testChecksumSanityPrefixWrongAlgorithm() {
String checksum = "{MD5}" + SHA256_NO_PREFIX_CHECKSUM;
DigestHelper.validateChecksumString(checksum);
}
@Test(expected = IllegalArgumentException.class)
public void testChecksumSanityPrefixWrongChecksumLength() {
String checksum = SHA256_CHECKSUM + "XXXXX";
DigestHelper.validateChecksumString(checksum);
}
}
//Generated with love by TestMe :) Please report issues and submit feature requests at: http://weirddev.com/forum#!/testme