From f51a08204972157505e72dd8050df7c61a6c61ba Mon Sep 17 00:00:00 2001 From: CalDescent Date: Tue, 17 Aug 2021 09:07:46 +0100 Subject: [PATCH] Validate the previous state's hash each time a new layer is applied. It's possible that this concept will struggle in the real world if operating systems, virus scanners, etc start interfering with our file stucture. Right now it is using a zero tolerance approach when checking the validity of each layer. We may choose to loosen this slightly if we encounter problems, e.g. by excluding hidden files. But for now it is best to be as strict as possible. --- .../arbitrary/ArbitraryDataCombiner.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataCombiner.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataCombiner.java index ccbfb85c..681a5949 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataCombiner.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataCombiner.java @@ -4,6 +4,7 @@ import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch; +import org.qortal.utils.Base58; import org.qortal.utils.FilesystemUtils; import java.io.File; @@ -32,6 +33,7 @@ public class ArbitraryDataCombiner { try { this.preExecute(); this.validatePreviousSignature(); + this.validatePreviousHash(); this.process(); } finally { @@ -101,6 +103,24 @@ public class ArbitraryDataCombiner { } } + private void validatePreviousHash() throws IOException { + ArbitraryDataMetadataPatch metadata = new ArbitraryDataMetadataPatch(this.pathAfter); + metadata.read(); + byte[] previousHash = metadata.getPreviousHash(); + if (previousHash == null) { + throw new IllegalStateException("Unable to extract previous hash from patch metadata"); + } + + ArbitraryDataDigest digest = new ArbitraryDataDigest(this.pathBefore); + digest.compute(); + boolean valid = digest.isHashValid(previousHash); + if (!valid) { + String previousHash58 = Base58.encode(previousHash); + throw new IllegalStateException(String.format("Previous state hash mismatch. " + + "Patch prevHash: %s, actual: %s", previousHash58, digest.getHash58())); + } + } + private void process() throws IOException { ArbitraryDataMerge merge = new ArbitraryDataMerge(this.pathBefore, this.pathAfter); merge.compute();