Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DDI supports SHA256 #869

Merged
merged 4 commits into from
Jul 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,14 @@ public ArtifactFilesystem getArtifactBySha1(final String tenant, final String sh
return null;
}

return new ArtifactFilesystem(file, sha1, new DbArtifactHash(sha1, null), file.length(), null);
return new ArtifactFilesystem(file, sha1, new DbArtifactHash(sha1, null, null), file.length(), null);
}

@Override
protected AbstractDbArtifact store(final String tenant, final String sha1Hash16, final String mdMD5Hash16,
final String contentType, final String tempFile) throws IOException {
protected AbstractDbArtifact store(final String tenant, final DbArtifactHash base16Hashes, final String contentType, final String tempFile) throws IOException {

final File file = new File(tempFile);
return renameFileToSHA1Naming(tenant, file, new ArtifactFilesystem(file, sha1Hash16,
new DbArtifactHash(sha1Hash16, mdMD5Hash16), file.length(), contentType));
return renameFileToSHA1Naming(tenant, file, new ArtifactFilesystem(file, base16Hashes.getSha1(), base16Hashes, file.length(), contentType));
}

private ArtifactFilesystem renameFileToSHA1Naming(final String tenant, final File file,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class ArtifactFilesystemTest {
public void getInputStreamOfNonExistingFileThrowsException() {
final File file = new File("fileWhichTotalDoesNotExists");
final ArtifactFilesystem underTest = new ArtifactFilesystem(file, "fileWhichTotalDoesNotExists",
new DbArtifactHash("1", "2"), 0L, null);
new DbArtifactHash("1", "2", "3"), 0L, null);
try {
underTest.getFileInputStream();
Assertions.fail("Expected a FileNotFoundException because file does not exists");
Expand All @@ -48,7 +48,7 @@ public void getInputStreamOfExistingFile() throws IOException {
createTempFile.deleteOnExit();

final ArtifactFilesystem underTest = new ArtifactFilesystem(createTempFile,
ArtifactFilesystemTest.class.getSimpleName(), new DbArtifactHash("1", "2"), 0L, null);
ArtifactFilesystemTest.class.getSimpleName(), new DbArtifactHash("1", "2", "3"), 0L, null);
final byte[] buffer = new byte[1024];
IOUtils.read(underTest.getFileInputStream(), buffer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,31 @@ public abstract class AbstractArtifactRepository implements ArtifactRepository {
// is not used security related
@SuppressWarnings("squid:S2070")
public AbstractDbArtifact store(final String tenant, final InputStream content, final String filename,
final String contentType, final DbArtifactHash hash) {
final String contentType, final DbArtifactHash providedHashes) {
final MessageDigest mdSHA1;
final MessageDigest mdMD5;
final MessageDigest mdSHA256;
try {
mdSHA1 = MessageDigest.getInstance("SHA1");
mdMD5 = MessageDigest.getInstance("MD5");
mdSHA256 = MessageDigest.getInstance("SHA-256");
} catch (final NoSuchAlgorithmException e) {
throw new ArtifactStoreException(e.getMessage(), e);
}

String tempFile = null;
try (final DigestInputStream inputstream = wrapInDigestInputStream(content, mdSHA1, mdMD5)) {
try (final DigestInputStream inputstream = wrapInDigestInputStream(content, mdSHA1, mdMD5, mdSHA256)) {

tempFile = storeTempFile(inputstream);

final String sha1Hash16 = BaseEncoding.base16().lowerCase().encode(mdSHA1.digest());
final String md5Hash16 = BaseEncoding.base16().lowerCase().encode(mdMD5.digest());
final String sha256Hash16 = BaseEncoding.base16().lowerCase().encode(mdSHA256.digest());

checkHashes(sha1Hash16, md5Hash16, hash);
checkHashes(sha1Hash16, md5Hash16, sha256Hash16, providedHashes);

return store(sanitizeTenant(tenant), sha1Hash16, md5Hash16, contentType, tempFile);
return store(sanitizeTenant(tenant), new DbArtifactHash(sha1Hash16, md5Hash16, sha256Hash16), contentType,
tempFile);
} catch (final IOException e) {
throw new ArtifactStoreException(e.getMessage(), e);
} finally {
Expand Down Expand Up @@ -100,27 +104,35 @@ private static File createTempFile() {
}
}

private static void checkHashes(final String sha1Hash16, final String md5Hash16, final DbArtifactHash hash) {
if (hash == null) {
private static void checkHashes(final String sha1Hash16, final String md5Hash16, final String sha256Hash16,
final DbArtifactHash providedHashes) {
if (providedHashes == null) {
return;
}
if (hash.getSha1() != null && !sha1Hash16.equals(hash.getSha1())) {
throw new HashNotMatchException("The given sha1 hash " + hash.getSha1()
+ " does not match with the calcualted sha1 hash " + sha1Hash16, HashNotMatchException.SHA1);
if (areHashesNotMatching(providedHashes.getSha1(), sha1Hash16)) {
throw new HashNotMatchException("The given sha1 hash " + providedHashes.getSha1()
+ " does not match the calculated sha1 hash " + sha1Hash16, HashNotMatchException.SHA1);
}
if (hash.getMd5() != null && !md5Hash16.equals(hash.getMd5())) {
throw new HashNotMatchException(
"The given md5 hash " + hash.getMd5() + " does not match with the calcualted md5 hash " + md5Hash16,
HashNotMatchException.MD5);
if (areHashesNotMatching(providedHashes.getMd5(), md5Hash16)) {
throw new HashNotMatchException("The given md5 hash " + providedHashes.getMd5()
+ " does not match the calculated md5 hash " + md5Hash16, HashNotMatchException.MD5);
}
if (areHashesNotMatching(providedHashes.getSha256(), sha256Hash16)) {
throw new HashNotMatchException("The given sha256 hash " + providedHashes.getSha256()
+ " does not match the calculated sha256 hash " + sha256Hash16, HashNotMatchException.SHA256);
}
}

private static boolean areHashesNotMatching(String providedHashValue, String hashValue) {
return providedHashValue != null && !hashValue.equals(providedHashValue);
}

protected abstract AbstractDbArtifact store(final String tenant, final String sha1Hash16, final String mdMD5Hash16,
protected abstract AbstractDbArtifact store(final String tenant, final DbArtifactHash base16Hashes,
final String contentType, final String tempFile) throws IOException;

private static DigestInputStream wrapInDigestInputStream(final InputStream input, final MessageDigest mdSHA1,
final MessageDigest mdMD5) {
return new DigestInputStream(new DigestInputStream(input, mdMD5), mdSHA1);
final MessageDigest mdMD5, final MessageDigest mdSHA256) {
return new DigestInputStream(new DigestInputStream(new DigestInputStream(input, mdSHA256), mdMD5), mdSHA1);
}

protected static String sanitizeTenant(final String tenant) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class HashNotMatchException extends RuntimeException {

public static final String SHA1 = "SHA-1";
public static final String MD5 = "MD5";
public static final String SHA256 = "SHA-256";

private final String hashFunction;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@ public class DbArtifactHash {

private final String md5;

private final String sha256;

/**
* Constructor.
*
* @param sha1
* the sha1 hash
* @param md5
* the md5 hash
* @param sha256
* the sha256 hash
*/
public DbArtifactHash(final String sha1, final String md5) {
public DbArtifactHash(final String sha1, final String md5, final String sha256) {
this.sha1 = sha1;
this.md5 = md5;
this.sha256 = sha256;
}

public String getSha1() {
Expand All @@ -39,4 +44,7 @@ public String getMd5() {
return md5;
}

public String getSha256() {
return sha256;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ public void testSendDownloadRequesWithSoftwareModulesAndNoArtifacts() {
}

@Test
@Description("Verifies that download and install event with software moduls and artifacts works")
@Description("Verifies that download and install event with software modules and artifacts works")
public void testSendDownloadRequest() {
DistributionSet dsA = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
SoftwareModule module = dsA.getModules().iterator().next();
final List<AbstractDbArtifact> receivedList = new ArrayList<>();
for (final Artifact artifact : testdataFactory.createArtifacts(module.getId())) {
receivedList.add(new ArtifactFilesystem(new File("./test"), artifact.getSha1Hash(),
new DbArtifactHash(artifact.getSha1Hash(), null), artifact.getSize(), null));
new DbArtifactHash(artifact.getSha1Hash(), null, null), artifact.getSize(), null));
}
module = softwareModuleManagement.get(module.getId()).get();
dsA = distributionSetManagement.get(dsA.getId()).get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public interface Artifact extends TenantAwareBaseEntity {
*/
String getSha1Hash();

/**
* @return SHA-256 hash of the artifact.
*/
String getSha256Hash();

/**
* @return size of the artifact in bytes.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class ArtifactUpload {

private final String providedSha1Sum;

private final String providedSha256Sum;

private final boolean overrideExisting;

private final String contentType;
Expand Down Expand Up @@ -90,6 +92,7 @@ public ArtifactUpload(final InputStream inputStream, final long moduleId, final
this.filename = filename;
this.providedMd5Sum = providedMd5Sum;
this.providedSha1Sum = providedSha1Sum;
this.providedSha256Sum = null;
this.overrideExisting = overrideExisting;
this.contentType = contentType;
this.filesize = filesize;
Expand All @@ -115,6 +118,10 @@ public String getProvidedSha1Sum() {
return providedSha1Sum;
}

public String getProvidedSha256Sum() {
return providedSha256Sum;
}

public boolean overrideExisting() {
return overrideExisting;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private AbstractDbArtifact storeArtifact(final ArtifactUpload artifactUpload) {
try {
return artifactRepository.store(tenantAware.getCurrentTenant(), artifactUpload.getInputStream(),
artifactUpload.getFilename(), artifactUpload.getContentType(),
new DbArtifactHash(artifactUpload.getProvidedSha1Sum(), artifactUpload.getProvidedMd5Sum()));
new DbArtifactHash(artifactUpload.getProvidedSha1Sum(), artifactUpload.getProvidedMd5Sum(), artifactUpload.getProvidedSha256Sum()));
} catch (final ArtifactStoreException e) {
throw new ArtifactUploadFailedException(e);
} catch (final HashNotMatchException e) {
Expand Down Expand Up @@ -256,6 +256,7 @@ private Artifact storeArtifactMetadata(final SoftwareModule softwareModule, fina
artifact = new JpaArtifact(result.getHashes().getSha1(), providedFilename, softwareModule);
}
artifact.setMd5Hash(result.getHashes().getMd5());
artifact.setSha256Hash(result.getHashes().getSha256());
artifact.setSha1Hash(result.getHashes().getSha1());
artifact.setSize(result.getSize());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public class JpaArtifact extends AbstractJpaTenantAwareBaseEntity implements Art
@Column(name = "md5_hash", length = 32, updatable = false, nullable = true)
private String md5Hash;

@Column(name = "sha256_hash", length = 64, updatable = false, nullable = true)
private String sha256Hash;

@Column(name = "file_size", updatable = false)
private long size;

Expand Down Expand Up @@ -94,6 +97,11 @@ public String getSha1Hash() {
return sha1Hash;
}

@Override
public String getSha256Hash() {
return sha256Hash;
}

public void setMd5Hash(final String md5Hash) {
this.md5Hash = md5Hash;
}
Expand All @@ -102,6 +110,11 @@ public void setSha1Hash(final String sha1Hash) {
this.sha1Hash = sha1Hash;
}

public void setSha256Hash(final String sha256Hash) {
this.sha256Hash = sha256Hash;
}


@Override
public long getSize() {
return size;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE sp_artifact ADD COLUMN sha256_hash CHAR(64);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE sp_artifact ADD COLUMN sha256_hash CHAR(64);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE sp_artifact ADD COLUMN sha256_hash CHAR(64);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE sp_artifact ADD sha256_hash CHAR(64);
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ public void createArtifact() throws IOException {
.isEqualTo(HashGeneratorUtils.generateSHA1(randomBytes));
assertThat(artifactManagement.getByFilename("file1").get().getMd5Hash())
.isEqualTo(HashGeneratorUtils.generateMD5(randomBytes));
assertThat(artifactManagement.getByFilename("file1").get().getSha256Hash())
.isEqualTo(HashGeneratorUtils.generateSHA256(randomBytes));

assertThat(artifactRepository.findAll()).hasSize(4);
assertThat(softwareModuleRepository.findAll()).hasSize(3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.ddi.json.model;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
Expand All @@ -23,6 +25,10 @@ public class DdiArtifactHash {
@JsonProperty
private String md5;

@JsonProperty
@JsonInclude(Include.NON_NULL)
private String sha256;

/**
* Default constructor.
*/
Expand All @@ -34,11 +40,16 @@ public DdiArtifactHash() {
* Public constructor.
*
* @param sha1
* sha1 hash of the artifact
* @param md5
* md5 hash of the artifact
* @param sha256
* sha256 hash of the artifact
*/
public DdiArtifactHash(final String sha1, final String md5) {
public DdiArtifactHash(final String sha1, final String md5, final String sha256) {
this.sha1 = sha1;
this.md5 = md5;
this.sha256 = sha256;
}

/**
Expand All @@ -55,4 +66,10 @@ public String getMd5() {
return md5;
}

/**
* @return the sha256
*/
public String getSha256() {
return sha256;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ static List<DdiArtifact> createArtifacts(final Target target, final SoftwareModu
private static DdiArtifact createArtifact(final Target target, final ArtifactUrlHandler artifactUrlHandler,
final Artifact artifact, final SystemManagement systemManagement, final HttpRequest request) {
final DdiArtifact file = new DdiArtifact();
file.setHashes(new DdiArtifactHash(artifact.getSha1Hash(), artifact.getMd5Hash()));
file.setHashes(new DdiArtifactHash(artifact.getSha1Hash(), artifact.getMd5Hash(), artifact.getSha256Hash()));
file.setFilename(artifact.getFilename());
file.setSize(artifact.getSize());

Expand Down
Loading