From 9b93afaf6fc3ce594c18b92ff3f1636e850fc36c Mon Sep 17 00:00:00 2001 From: Gregor Gaertner Date: Mon, 18 Jan 2021 12:15:35 +0100 Subject: [PATCH] Introduced exception handling for wrong payload sizes (in StreamDeserializationContext) and wrong URIs (in PendingAttestation). Fixed broken test in TestUnknownAttestation, detailed tests for wrong URIs in TestPendingAttestation. Added new exceptions to all methods in source or tests where exceptions can occur. --- .../java/com/eternitywall/ots/Calendar.java | 9 ++--- .../ots/DetachedTimestampFile.java | 5 +-- .../java/com/eternitywall/ots/OtsCli.java | 3 ++ .../ots/StreamDeserializationContext.java | 17 ++++++---- .../java/com/eternitywall/ots/Timestamp.java | 9 +++-- .../ots/attestation/PendingAttestation.java | 16 ++++++--- .../ots/attestation/TimeAttestation.java | 3 +- .../ots/attestation/UnknownAttestation.java | 3 +- .../exceptions/DeserializationException.java | 7 ++++ .../ots/exceptions/ExceededSizeException.java | 6 ++-- src/main/java/com/eternitywall/ots/op/Op.java | 6 ++-- .../com/eternitywall/ots/op/OpAppend.java | 4 ++- .../com/eternitywall/ots/op/OpBinary.java | 4 ++- .../com/eternitywall/ots/op/OpPrepend.java | 4 ++- .../com/eternitywall/TestLongReceipt.java | 3 +- .../com/eternitywall/TestOpenTimestamps.java | 7 ++-- .../TestStreamDeserializationContext.java | 5 +-- .../java/com/eternitywall/TestTimestamp.java | 7 ++-- .../TestBitcoinBlockHeaderAttestation.java | 3 +- .../attestation/TestPendingAttestation.java | 34 ++++++++++++------- .../attestation/TestUnknownAttestation.java | 22 +++++++----- 21 files changed, 117 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/eternitywall/ots/exceptions/DeserializationException.java diff --git a/src/main/java/com/eternitywall/ots/Calendar.java b/src/main/java/com/eternitywall/ots/Calendar.java index 7baa30e..e700593 100644 --- a/src/main/java/com/eternitywall/ots/Calendar.java +++ b/src/main/java/com/eternitywall/ots/Calendar.java @@ -3,6 +3,7 @@ import com.eternitywall.http.Request; import com.eternitywall.http.Response; import com.eternitywall.ots.exceptions.CommitmentNotFoundException; +import com.eternitywall.ots.exceptions.DeserializationException; import com.eternitywall.ots.exceptions.ExceededSizeException; import com.eternitywall.ots.exceptions.UrlException; import org.bitcoinj.core.ECKey; @@ -63,7 +64,7 @@ public String getUrl() { * * @param digest The digest hash to send. * @return the Timestamp received from the calendar. - * @throws ExceededSizeException if response is too big. + * @throws DeserializationException if response is too big. * @throws UrlException if url is not reachable. */ public Timestamp submit(byte[] digest) throws ExceededSizeException, UrlException { @@ -100,11 +101,11 @@ public Timestamp submit(byte[] digest) throws ExceededSizeException, UrlExceptio * * @param commitment The digest hash to send. * @return the Timestamp from the calendar server (with blockchain information if already written). - * @throws ExceededSizeException if response is too big. + * @throws DeserializationException if response is too big. * @throws UrlException if url is not reachable. * @throws CommitmentNotFoundException if commit is not found. */ - public Timestamp getTimestamp(byte[] commitment) throws ExceededSizeException, CommitmentNotFoundException, UrlException { + public Timestamp getTimestamp(byte[] commitment) throws DeserializationException, CommitmentNotFoundException, UrlException { try { Map headers = new HashMap<>(); headers.put("Accept", "application/vnd.opentimestamps.v1"); @@ -117,7 +118,7 @@ public Timestamp getTimestamp(byte[] commitment) throws ExceededSizeException, C Response response = task.call(); byte[] body = response.getBytes(); if (body.length > 10000) { - throw new ExceededSizeException("Calendar response exceeded size limit"); + throw new DeserializationException("Calendar response exceeded size limit"); } if (!response.isOk()) { diff --git a/src/main/java/com/eternitywall/ots/DetachedTimestampFile.java b/src/main/java/com/eternitywall/ots/DetachedTimestampFile.java index b42916c..f2360bf 100644 --- a/src/main/java/com/eternitywall/ots/DetachedTimestampFile.java +++ b/src/main/java/com/eternitywall/ots/DetachedTimestampFile.java @@ -1,5 +1,6 @@ package com.eternitywall.ots; +import com.eternitywall.ots.exceptions.DeserializationException; import com.eternitywall.ots.op.Op; import com.eternitywall.ots.op.OpCrypto; import com.eternitywall.ots.op.OpSHA256; @@ -96,7 +97,7 @@ public byte[] serialize() { * @param ctx The stream deserialization context. * @return The generated com.eternitywall.ots.DetachedTimestampFile object. */ - public static DetachedTimestampFile deserialize(StreamDeserializationContext ctx) { + public static DetachedTimestampFile deserialize(StreamDeserializationContext ctx) throws DeserializationException { ctx.assertMagic(HEADER_MAGIC); ctx.readVaruint(); @@ -115,7 +116,7 @@ public static DetachedTimestampFile deserialize(StreamDeserializationContext ctx * @param ots The byte array of deserialization DetachedFileTimestamped. * @return The generated com.eternitywall.ots.DetachedTimestampFile object. */ - public static DetachedTimestampFile deserialize(byte[] ots) { + public static DetachedTimestampFile deserialize(byte[] ots) throws DeserializationException { StreamDeserializationContext ctx = new StreamDeserializationContext(ots); return DetachedTimestampFile.deserialize(ctx); diff --git a/src/main/java/com/eternitywall/ots/OtsCli.java b/src/main/java/com/eternitywall/ots/OtsCli.java index 06ba670..81179ab 100644 --- a/src/main/java/com/eternitywall/ots/OtsCli.java +++ b/src/main/java/com/eternitywall/ots/OtsCli.java @@ -3,6 +3,7 @@ import com.eternitywall.ots.attestation.BitcoinBlockHeaderAttestation; import com.eternitywall.ots.attestation.EthereumBlockHeaderAttestation; import com.eternitywall.ots.attestation.LitecoinBlockHeaderAttestation; +import com.eternitywall.ots.exceptions.DeserializationException; import com.eternitywall.ots.op.OpSHA256; import org.apache.commons.cli.BasicParser; import org.apache.commons.cli.CommandLine; @@ -216,6 +217,8 @@ public static void info(String argsOts, boolean verbose) { System.out.println(infoResult); } catch (IOException e) { log.severe("No valid file"); + } catch (DeserializationException e) { + log.severe("Deserialization error: size was either too long or short"); } } diff --git a/src/main/java/com/eternitywall/ots/StreamDeserializationContext.java b/src/main/java/com/eternitywall/ots/StreamDeserializationContext.java index 183a86f..0113e53 100644 --- a/src/main/java/com/eternitywall/ots/StreamDeserializationContext.java +++ b/src/main/java/com/eternitywall/ots/StreamDeserializationContext.java @@ -1,5 +1,6 @@ package com.eternitywall.ots; +import com.eternitywall.ots.exceptions.DeserializationException; import java.util.Arrays; import java.util.logging.Logger; @@ -65,7 +66,9 @@ public int readVaruint() { return value; } - public byte[] readBytes(int expectedLength) { + public byte[] readBytes(int expectedLength) throws DeserializationException { + + if (expectedLength == 0) { return this.readVarbytes(1024, 0); } @@ -73,19 +76,19 @@ public byte[] readBytes(int expectedLength) { return this.read(expectedLength); } - public byte[] readVarbytes(int maxLen) { + public byte[] readVarbytes(int maxLen) throws DeserializationException { return readVarbytes(maxLen, 0); } - public byte[] readVarbytes(int maxLen, int minLen) { + public byte[] readVarbytes(int maxLen, int minLen) throws DeserializationException { int l = this.readVaruint(); - if ((l & 0xff) > maxLen) { + if (l > maxLen) { log.severe("varbytes max length exceeded;"); - return null; - } else if ((l & 0xff) < minLen) { + throw new DeserializationException("varbytes max length exceeded;"); + } else if (l < minLen) { log.severe("varbytes min length not met;"); - return null; + throw new DeserializationException("varbytes min length not met;"); } return this.read(l); diff --git a/src/main/java/com/eternitywall/ots/Timestamp.java b/src/main/java/com/eternitywall/ots/Timestamp.java index 33044d6..408a75a 100644 --- a/src/main/java/com/eternitywall/ots/Timestamp.java +++ b/src/main/java/com/eternitywall/ots/Timestamp.java @@ -2,6 +2,7 @@ import com.eternitywall.ots.attestation.BitcoinBlockHeaderAttestation; import com.eternitywall.ots.attestation.TimeAttestation; +import com.eternitywall.ots.exceptions.DeserializationException; import com.eternitywall.ots.op.Op; import com.eternitywall.ots.op.OpBinary; import com.eternitywall.ots.op.OpSHA256; @@ -44,7 +45,7 @@ public Timestamp(byte[] msg) { * @param initialMsg - The initial message. * @return The deserialized Timestamp. */ - public static Timestamp deserialize(byte[] ots, byte[] initialMsg) { + public static Timestamp deserialize(byte[] ots, byte[] initialMsg) throws DeserializationException { StreamDeserializationContext ctx = new StreamDeserializationContext(ots); return Timestamp.deserialize(ctx, initialMsg); @@ -63,7 +64,8 @@ public static Timestamp deserialize(byte[] ots, byte[] initialMsg) { * @param initialMsg - The initial message. * @return The deserialized Timestamp. */ - public static Timestamp deserialize(StreamDeserializationContext ctx, byte[] initialMsg) { + public static Timestamp deserialize(StreamDeserializationContext ctx, byte[] initialMsg) + throws DeserializationException { Timestamp self = new Timestamp(initialMsg); byte tag = ctx.readBytes(1)[0]; @@ -78,7 +80,8 @@ public static Timestamp deserialize(StreamDeserializationContext ctx, byte[] ini return self; } - private static void doTagOrAttestation(Timestamp self, StreamDeserializationContext ctx, byte tag, byte[] initialMsg) { + private static void doTagOrAttestation(Timestamp self, StreamDeserializationContext ctx, byte tag, byte[] initialMsg) + throws DeserializationException { if ((tag & 0xff) == 0x00) { TimeAttestation attestation = TimeAttestation.deserialize(ctx); self.attestations.add(attestation); diff --git a/src/main/java/com/eternitywall/ots/attestation/PendingAttestation.java b/src/main/java/com/eternitywall/ots/attestation/PendingAttestation.java index 44af972..8a52d82 100644 --- a/src/main/java/com/eternitywall/ots/attestation/PendingAttestation.java +++ b/src/main/java/com/eternitywall/ots/attestation/PendingAttestation.java @@ -4,6 +4,7 @@ import com.eternitywall.ots.StreamSerializationContext; import com.eternitywall.ots.Utils; +import com.eternitywall.ots.exceptions.DeserializationException; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.logging.Logger; @@ -74,13 +75,20 @@ public static boolean checkUri(byte[] uri) { return true; } - public static PendingAttestation deserialize(StreamDeserializationContext ctxPayload) { - byte[] utf8Uri = ctxPayload.readVarbytes(PendingAttestation._MAX_URI_LENGTH); + public static PendingAttestation deserialize(StreamDeserializationContext ctxPayload) + throws DeserializationException { + + byte[] utf8Uri; + try { + utf8Uri = ctxPayload.readVarbytes(PendingAttestation._MAX_URI_LENGTH); + } catch (DeserializationException e) { + log.severe("URI too long and thus invalid: "); + throw new DeserializationException("Invalid URI: "); + } if (PendingAttestation.checkUri(utf8Uri) == false) { log.severe("Invalid URI: "); - - return null; + throw new DeserializationException("Invalid URI: "); } return new PendingAttestation(utf8Uri); diff --git a/src/main/java/com/eternitywall/ots/attestation/TimeAttestation.java b/src/main/java/com/eternitywall/ots/attestation/TimeAttestation.java index b2f52d1..1a8ad16 100644 --- a/src/main/java/com/eternitywall/ots/attestation/TimeAttestation.java +++ b/src/main/java/com/eternitywall/ots/attestation/TimeAttestation.java @@ -4,6 +4,7 @@ import com.eternitywall.ots.StreamSerializationContext; import com.eternitywall.ots.Utils; +import com.eternitywall.ots.exceptions.DeserializationException; import java.util.Arrays; import java.util.logging.Logger; @@ -30,7 +31,7 @@ public byte[] _TAG() { * @param ctx The stream deserialization context. * @return The specific subclass Attestation. */ - public static TimeAttestation deserialize(StreamDeserializationContext ctx) { + public static TimeAttestation deserialize(StreamDeserializationContext ctx) throws DeserializationException { // console.log('attestation deserialize'); byte[] tag = ctx.readBytes(_TAG_SIZE); diff --git a/src/main/java/com/eternitywall/ots/attestation/UnknownAttestation.java b/src/main/java/com/eternitywall/ots/attestation/UnknownAttestation.java index 4d4d038..5bfb019 100644 --- a/src/main/java/com/eternitywall/ots/attestation/UnknownAttestation.java +++ b/src/main/java/com/eternitywall/ots/attestation/UnknownAttestation.java @@ -4,6 +4,7 @@ import com.eternitywall.ots.StreamSerializationContext; import com.eternitywall.ots.Utils; +import com.eternitywall.ots.exceptions.DeserializationException; import java.util.Arrays; import java.util.logging.Logger; @@ -36,7 +37,7 @@ public void serializePayload(StreamSerializationContext ctx) { ctx.writeBytes(this.payload); } - public static UnknownAttestation deserialize(StreamDeserializationContext ctxPayload, byte[] tag) { + public static UnknownAttestation deserialize(StreamDeserializationContext ctxPayload, byte[] tag) throws DeserializationException { byte[] payload = ctxPayload.readVarbytes(_MAX_PAYLOAD_SIZE); return new UnknownAttestation(tag, payload); diff --git a/src/main/java/com/eternitywall/ots/exceptions/DeserializationException.java b/src/main/java/com/eternitywall/ots/exceptions/DeserializationException.java new file mode 100644 index 0000000..7df2a18 --- /dev/null +++ b/src/main/java/com/eternitywall/ots/exceptions/DeserializationException.java @@ -0,0 +1,7 @@ +package com.eternitywall.ots.exceptions; + +public class DeserializationException extends Exception { + public DeserializationException(String message) { + super(message); + } +} diff --git a/src/main/java/com/eternitywall/ots/exceptions/ExceededSizeException.java b/src/main/java/com/eternitywall/ots/exceptions/ExceededSizeException.java index 038f955..addc389 100644 --- a/src/main/java/com/eternitywall/ots/exceptions/ExceededSizeException.java +++ b/src/main/java/com/eternitywall/ots/exceptions/ExceededSizeException.java @@ -1,7 +1,7 @@ package com.eternitywall.ots.exceptions; public class ExceededSizeException extends Exception { - public ExceededSizeException(String message) { - super(message); - } + public ExceededSizeException(String message) { + super(message); + } } diff --git a/src/main/java/com/eternitywall/ots/op/Op.java b/src/main/java/com/eternitywall/ots/op/Op.java index 68b7199..0befcd7 100644 --- a/src/main/java/com/eternitywall/ots/op/Op.java +++ b/src/main/java/com/eternitywall/ots/op/Op.java @@ -4,6 +4,7 @@ import com.eternitywall.ots.StreamSerializationContext; import com.eternitywall.ots.Utils; +import com.eternitywall.ots.exceptions.DeserializationException; import java.util.logging.Logger; /** @@ -61,7 +62,7 @@ public byte _TAG() { * @param ctx The stream deserialization context. * @return The subclass Operation. */ - public static Op deserialize(StreamDeserializationContext ctx) { + public static Op deserialize(StreamDeserializationContext ctx) throws DeserializationException { byte tag = ctx.readBytes(1)[0]; return Op.deserializeFromTag(ctx, tag); @@ -74,7 +75,8 @@ public static Op deserialize(StreamDeserializationContext ctx) { * @param tag The tag of the operation. * @return The subclass Operation. */ - public static Op deserializeFromTag(StreamDeserializationContext ctx, byte tag) { + public static Op deserializeFromTag(StreamDeserializationContext ctx, byte tag) + throws DeserializationException { if (tag == OpAppend._TAG) { return OpAppend.deserializeFromTag(ctx, tag); } else if (tag == OpPrepend._TAG) { diff --git a/src/main/java/com/eternitywall/ots/op/OpAppend.java b/src/main/java/com/eternitywall/ots/op/OpAppend.java index b0940af..8abac51 100644 --- a/src/main/java/com/eternitywall/ots/op/OpAppend.java +++ b/src/main/java/com/eternitywall/ots/op/OpAppend.java @@ -3,6 +3,7 @@ import com.eternitywall.ots.StreamDeserializationContext; import com.eternitywall.ots.Utils; +import com.eternitywall.ots.exceptions.DeserializationException; import java.util.Arrays; import java.util.logging.Logger; @@ -44,7 +45,8 @@ public byte[] call(byte[] msg) { return Utils.arraysConcat(msg, this.arg); } - public static Op deserializeFromTag(StreamDeserializationContext ctx, byte tag) { + public static Op deserializeFromTag(StreamDeserializationContext ctx, byte tag) + throws DeserializationException { return OpBinary.deserializeFromTag(ctx, tag); } diff --git a/src/main/java/com/eternitywall/ots/op/OpBinary.java b/src/main/java/com/eternitywall/ots/op/OpBinary.java index e3dff12..a495227 100644 --- a/src/main/java/com/eternitywall/ots/op/OpBinary.java +++ b/src/main/java/com/eternitywall/ots/op/OpBinary.java @@ -4,6 +4,7 @@ import com.eternitywall.ots.StreamSerializationContext; import com.eternitywall.ots.Utils; +import com.eternitywall.ots.exceptions.DeserializationException; import java.util.Arrays; import java.util.logging.Logger; @@ -33,7 +34,8 @@ public OpBinary(byte[] arg_) { this.arg = arg_; } - public static Op deserializeFromTag(StreamDeserializationContext ctx, byte tag) { + public static Op deserializeFromTag(StreamDeserializationContext ctx, byte tag) + throws DeserializationException { byte[] arg = ctx.readVarbytes(_MAX_RESULT_LENGTH, 1); if (tag == OpAppend._TAG) { diff --git a/src/main/java/com/eternitywall/ots/op/OpPrepend.java b/src/main/java/com/eternitywall/ots/op/OpPrepend.java index 153348f..b2560f9 100644 --- a/src/main/java/com/eternitywall/ots/op/OpPrepend.java +++ b/src/main/java/com/eternitywall/ots/op/OpPrepend.java @@ -3,6 +3,7 @@ import com.eternitywall.ots.StreamDeserializationContext; import com.eternitywall.ots.Utils; +import com.eternitywall.ots.exceptions.DeserializationException; import java.util.Arrays; import java.util.logging.Logger; @@ -44,7 +45,8 @@ public byte[] call(byte[] msg) { return Utils.arraysConcat(this.arg, msg); } - public static Op deserializeFromTag(StreamDeserializationContext ctx, byte tag) { + public static Op deserializeFromTag(StreamDeserializationContext ctx, byte tag) + throws DeserializationException { return OpBinary.deserializeFromTag(ctx, tag); } diff --git a/src/test/java/com/eternitywall/TestLongReceipt.java b/src/test/java/com/eternitywall/TestLongReceipt.java index d43cc06..10e9d89 100644 --- a/src/test/java/com/eternitywall/TestLongReceipt.java +++ b/src/test/java/com/eternitywall/TestLongReceipt.java @@ -3,6 +3,7 @@ import com.eternitywall.ots.StreamDeserializationContext; import com.eternitywall.ots.StreamSerializationContext; import com.eternitywall.ots.Timestamp; +import com.eternitywall.ots.exceptions.DeserializationException; import org.junit.Test; import javax.xml.bind.DatatypeConverter; @@ -13,7 +14,7 @@ public class TestLongReceipt { @Test - public void testException() { + public void testException() throws DeserializationException { String digest = "c858838f62f908c922f9cd734e49c8fa6ee9a3b8a77093ac0969cba429249412"; byte[] digestByte = DatatypeConverter.parseHexBinary(digest); Timestamp root = new Timestamp(digestByte); diff --git a/src/test/java/com/eternitywall/TestOpenTimestamps.java b/src/test/java/com/eternitywall/TestOpenTimestamps.java index 4f0b166..f182927 100644 --- a/src/test/java/com/eternitywall/TestOpenTimestamps.java +++ b/src/test/java/com/eternitywall/TestOpenTimestamps.java @@ -11,6 +11,7 @@ import com.eternitywall.ots.Utils; import com.eternitywall.ots.VerifyResult; import com.eternitywall.ots.attestation.TimeAttestation; +import com.eternitywall.ots.exceptions.DeserializationException; import com.eternitywall.ots.exceptions.VerificationException; import com.eternitywall.ots.op.OpSHA256; import org.junit.After; @@ -79,7 +80,7 @@ public void loadData() throws ExecutionException, InterruptedException, IOExcept } @Test - public void info() { + public void info() throws DeserializationException { String result1 = OpenTimestamps.info(DetachedTimestampFile.deserialize(incompleteOts)); assertNotNull(result1); assertNotNull(incompleteOtsInfo); @@ -157,7 +158,7 @@ public void verify2() throws Exception { } @Test - public void verify() throws NoSuchAlgorithmException, IOException { + public void verify() throws NoSuchAlgorithmException, IOException, DeserializationException { { DetachedTimestampFile detachedOts = DetachedTimestampFile.deserialize(helloWorldOts); DetachedTimestampFile detached = DetachedTimestampFile.from(Hash.from(helloWorld, OpSHA256._TAG)); @@ -226,7 +227,7 @@ public void upgrade() { } @Test - public void test() { + public void test() throws DeserializationException { byte[] ots = Utils.hexToBytes("F0105C3F2B3F8524A32854E07AD8ADDE9C1908F10458D95A36F008088D287213A8B9880083DFE30D2EF90C8E2C2B68747470733A2F2F626F622E6274632E63616C656E6461722E6F70656E74696D657374616D70732E6F7267"); byte[] digest = Utils.hexToBytes("7aa9273d2a50dbe0cc5a6ccc444a5ca90c9491dd2ac91849e45195ae46f64fe352c3a63ba02775642c96131df39b5b85"); diff --git a/src/test/java/com/eternitywall/TestStreamDeserializationContext.java b/src/test/java/com/eternitywall/TestStreamDeserializationContext.java index de8ddfd..52ff9d0 100644 --- a/src/test/java/com/eternitywall/TestStreamDeserializationContext.java +++ b/src/test/java/com/eternitywall/TestStreamDeserializationContext.java @@ -6,6 +6,7 @@ import com.eternitywall.ots.Utils; import com.eternitywall.ots.attestation.PendingAttestation; import com.eternitywall.ots.attestation.TimeAttestation; +import com.eternitywall.ots.exceptions.DeserializationException; import org.junit.Test; import java.nio.charset.StandardCharsets; @@ -31,7 +32,7 @@ public void testVaruint() { } @Test - public void testReadvaruint() { + public void testReadvaruint() throws DeserializationException { final byte[] uri = "https://finney.calendar.eternitywall.com".getBytes(StandardCharsets.US_ASCII); PendingAttestation pendingAttestation = new PendingAttestation(uri); @@ -45,7 +46,7 @@ public void testReadvaruint() { } @Test - public void testTimestamp() { + public void testTimestamp() throws DeserializationException { byte[] ots = Utils.hexToBytes("F0105C3F2B3F8524A32854E07AD8ADDE9C1908F10458D95A36F008088D287213A8B9880083DFE30D2EF90C8E2C2B68747470733A2F2F626F622E6274632E63616C656E6461722E6F70656E74696D657374616D70732E6F7267"); byte[] digest = Utils.hexToBytes("7aa9273d2a50dbe0cc5a6ccc444a5ca90c9491dd2ac91849e45195ae46f64fe352c3a63ba02775642c96131df39b5b85"); diff --git a/src/test/java/com/eternitywall/TestTimestamp.java b/src/test/java/com/eternitywall/TestTimestamp.java index 3ac1a2a..b9bd1bf 100644 --- a/src/test/java/com/eternitywall/TestTimestamp.java +++ b/src/test/java/com/eternitywall/TestTimestamp.java @@ -6,6 +6,7 @@ import com.eternitywall.ots.Timestamp; import static com.eternitywall.ots.Utils.hexToBytes; import com.eternitywall.ots.attestation.PendingAttestation; +import com.eternitywall.ots.exceptions.DeserializationException; import com.eternitywall.ots.op.Op; import com.eternitywall.ots.op.OpAppend; import com.eternitywall.ots.op.OpSHA256; @@ -54,7 +55,8 @@ public void testSettingAnOpResultTimestamp() { } } - private void tSerialize(Timestamp expectedInstance, byte[] expectedSerialized) { + private void tSerialize(Timestamp expectedInstance, byte[] expectedSerialized) + throws DeserializationException { StreamSerializationContext ssc = new StreamSerializationContext(); expectedInstance.serialize(ssc); byte[] actualSerialized = ssc.getOutput(); @@ -67,7 +69,8 @@ private void tSerialize(Timestamp expectedInstance, byte[] expectedSerialized) { } @Test - public void testTimestampSerializationDeserialization() throws IOException { + public void testTimestampSerializationDeserialization() + throws IOException, DeserializationException { Timestamp stamp = new Timestamp(toBytes("foo", "UTF-8")); stamp.attestations.add(new PendingAttestation(toBytes("foobar", "UTF-8"))); diff --git a/src/test/java/com/eternitywall/ots/attestation/TestBitcoinBlockHeaderAttestation.java b/src/test/java/com/eternitywall/ots/attestation/TestBitcoinBlockHeaderAttestation.java index 2ba6ef2..2273a33 100644 --- a/src/test/java/com/eternitywall/ots/attestation/TestBitcoinBlockHeaderAttestation.java +++ b/src/test/java/com/eternitywall/ots/attestation/TestBitcoinBlockHeaderAttestation.java @@ -2,6 +2,7 @@ import com.eternitywall.ots.StreamDeserializationContext; import com.eternitywall.ots.Utils; +import com.eternitywall.ots.exceptions.DeserializationException; import org.junit.Test; import java.io.ByteArrayOutputStream; @@ -10,7 +11,7 @@ public class TestBitcoinBlockHeaderAttestation { @Test - public void deserializationTrailingGarbage() throws IOException { + public void deserializationTrailingGarbage() throws IOException, DeserializationException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(Utils.hexToBytes("0588960d73d71901" + "02" + // two bytes of payload diff --git a/src/test/java/com/eternitywall/ots/attestation/TestPendingAttestation.java b/src/test/java/com/eternitywall/ots/attestation/TestPendingAttestation.java index 3cef926..de91703 100644 --- a/src/test/java/com/eternitywall/ots/attestation/TestPendingAttestation.java +++ b/src/test/java/com/eternitywall/ots/attestation/TestPendingAttestation.java @@ -3,6 +3,8 @@ import com.eternitywall.ots.StreamDeserializationContext; import com.eternitywall.ots.StreamSerializationContext; import static com.eternitywall.ots.Utils.hexToBytes; + +import com.eternitywall.ots.exceptions.DeserializationException; import org.junit.Test; import javax.xml.bind.DatatypeConverter; @@ -16,7 +18,7 @@ public class TestPendingAttestation { @Test - public void testSerializationOfPendingAttestations() throws IOException { + public void testSerializationOfPendingAttestations() throws IOException, DeserializationException { PendingAttestation pendingAttestation = new PendingAttestation(toBytes("foobar", "UTF-8")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -47,39 +49,45 @@ public void testDeserializationOfAttestations() throws IOException { assertArrayEquals(expectedSerialized, ctx.getOutput()); } - @Test - public void testInvalidUriDeserialization() throws IOException { + @Test(expected = DeserializationException.class) + public void testInvalidUriDeserialization1() throws IOException, DeserializationException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(hexToBytes("83dfe30d2ef90c8e" + "07" + "06")); baos.write(toBytes("fo%bar", "UTF-8")); StreamDeserializationContext ctx = new StreamDeserializationContext(baos.toByteArray()); TimeAttestation.deserialize(ctx); - // TODO exception DeserializationError + } - // Too long + @Test + public void testInvalidUriDeserialization2() throws IOException, DeserializationException { + //This one is correct size and should throw no exception // Exactly 1000 bytes is ok - baos = new ByteArrayOutputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(hexToBytes("83dfe30d2ef90c8e" + "ea07" + "e807")); byte[] buffer = new byte[1000]; Arrays.fill(buffer, (byte) 'x'); baos.write(buffer); - ctx = new StreamDeserializationContext(baos.toByteArray()); + StreamDeserializationContext ctx = new StreamDeserializationContext(baos.toByteArray()); TimeAttestation.deserialize(ctx); + } - // But 1001 isn't - baos = new ByteArrayOutputStream(); + @Test(expected = DeserializationException.class) + public void testInvalidUriDeserialization3() throws IOException, DeserializationException { + // Exactly 1000 bytes was ok (in the previous test). + // But 1001 isn't, so this test should raise an exception + ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(hexToBytes("83dfe30d2ef90c8e" + "eb07" + "e907")); - buffer = new byte[1001]; + byte[] buffer = new byte[1001]; Arrays.fill(buffer, (byte) 'x'); baos.write(buffer); - ctx = new StreamDeserializationContext(baos.toByteArray()); + StreamDeserializationContext ctx = new StreamDeserializationContext(baos.toByteArray()); TimeAttestation.deserialize(ctx); - // TODO exception DeserializationError } + @Test - public void testDeserializationTrailingGarbage() throws IOException { + public void testDeserializationTrailingGarbage() throws IOException, DeserializationException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(hexToBytes("83dfe30d2ef90c8e" + "08" + "06")); baos.write(toBytes("foobarx", "UTF-8")); diff --git a/src/test/java/com/eternitywall/ots/attestation/TestUnknownAttestation.java b/src/test/java/com/eternitywall/ots/attestation/TestUnknownAttestation.java index fdb916e..b2b37b5 100644 --- a/src/test/java/com/eternitywall/ots/attestation/TestUnknownAttestation.java +++ b/src/test/java/com/eternitywall/ots/attestation/TestUnknownAttestation.java @@ -4,6 +4,8 @@ import com.eternitywall.ots.StreamSerializationContext; import static com.eternitywall.ots.Utils.hexToBytes; import static com.eternitywall.ots.Utils.bytesToHex; + +import com.eternitywall.ots.exceptions.DeserializationException; import org.junit.Test; import java.io.ByteArrayOutputStream; @@ -25,7 +27,8 @@ public void string() { } @Test - public void testSerializationDeserializationOfUnknownAttestations() throws IOException { + public void testSerializationDeserializationOfUnknownAttestations() + throws IOException, DeserializationException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(hexToBytes("0102030405060708")); baos.write(0x0c); @@ -42,26 +45,29 @@ public void testSerializationDeserializationOfUnknownAttestations() throws IOExc assertArrayEquals(expectedSerialized, ctx1.getOutput()); } - @Test - public void deserializationTooLong() throws IOException { + @Test(expected = DeserializationException.class ) + public void deserializationTooLong1() throws IOException, DeserializationException { // Deserialization of attestations with oversized payloads ByteArrayOutputStream baos1 = new ByteArrayOutputStream(); baos1.write(hexToBytes("0102030405060708")); baos1.write(0x81); baos1.write(0x40); - baos1.write('x' * 8193); + for(int i=0;i<8193;i++) + baos1.write('x'); StreamDeserializationContext ctx = new StreamDeserializationContext(baos1.toByteArray()); UnknownAttestation a = (UnknownAttestation) TimeAttestation.deserialize(ctx); - // TODO: exception + } + @Test(expected = DeserializationException.class ) + public void deserializationTooLong2() throws IOException, DeserializationException { // Pending attestation ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); baos2.write(hexToBytes("83dfe30d2ef90c8e")); baos2.write(0x81); baos2.write(0x40); - baos2.write('x' * 8193); + for(int i=0;i<8193;i++) + baos2.write('x'); StreamDeserializationContext ctx1 = new StreamDeserializationContext(baos2.toByteArray()); - UnknownAttestation a1 = (UnknownAttestation) TimeAttestation.deserialize(ctx1); - // TODO: exception + PendingAttestation a1 = (PendingAttestation) TimeAttestation.deserialize(ctx1); } }