diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java
new file mode 100644
index 00000000..c0f4a82a
--- /dev/null
+++ b/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java
@@ -0,0 +1,470 @@
+package hirs.data.persist;
+
+import java.util.Arrays;
+
+import hirs.utils.digest.Digest;
+import hirs.utils.digest.DigestAlgorithm;
+import hirs.utils.digest.DigestComparisonResultType;
+import org.apache.commons.codec.digest.DigestUtils;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for the Digest
class.
+ */
+public class DigestTest {
+ private static final int DIGEST_LENGTH_BYTES = 20;
+
+ /**
+ * Tests that constructor throws a IllegalArgumentException
when a
+ * null DigestAlgorithm
is passed into constructor.
+ */
+ @Test
+ public final void nullAlgorithm() {
+ final byte[] digest = getTestDigest(16);
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(null, digest));
+ }
+
+ /**
+ * Tests that constructor throws a IllegalArgumentException
when a
+ * null digest is passed into constructor.
+ */
+ @Test
+ public final void nullDigest() {
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(DigestAlgorithm.MD2, null));
+ }
+
+ /**
+ * Tests that constructor throws a IllegalArgumentException
when an
+ * digest that is an empty array is passed into constructor.
+ */
+ @Test
+ public final void emptyArrayDigest() {
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(DigestAlgorithm.MD2, new byte[0]));
+ }
+
+ /**
+ * Tests that MD2 digest can be created.
+ */
+ @Test
+ public final void md2() {
+ final byte[] digest = getTestDigest(16);
+ final Digest d = new Digest(DigestAlgorithm.MD2, digest);
+ Assertions.assertNotNull(d);
+ }
+
+ /**
+ * Tests that an MD2 digest can be recreated from a string.
+ */
+ @Test
+ public final void testFromStringMD2() {
+ final byte[] digestBytes = getTestDigest(16);
+ Digest digest = new Digest(DigestAlgorithm.MD2, digestBytes);
+ String digestString = digest.toString();
+ Digest digestFromString = Digest.fromString(digestString);
+ Assertions.assertEquals(digest, digestFromString);
+ }
+
+ /**
+ * Tests that MD2 digest cannot be created with a digest that has extra
+ * bytes.
+ */
+ @Test
+ public final void md2IllegalDigest() {
+ final byte[] digest = getTestDigest(17);
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(DigestAlgorithm.MD2, digest));
+ }
+
+ /**
+ * Tests that MD5 digest can be created.
+ */
+ @Test
+ public final void md5() {
+ final byte[] digest = getTestDigest(16);
+ final Digest d = new Digest(DigestAlgorithm.MD5, digest);
+ Assertions.assertNotNull(d);
+ }
+
+ /**
+ * Tests that an MD5 digest can be recreated from a string.
+ */
+ @Test
+ public final void testFromStringMD5() {
+ final byte[] digestBytes = getTestDigest(16);
+ Digest digest = new Digest(DigestAlgorithm.MD5, digestBytes);
+ String digestString = digest.toString();
+ Digest digestFromString = Digest.fromString(digestString);
+ Assertions.assertEquals(digest, digestFromString);
+ }
+
+ /**
+ * Tests that MD5 digest cannot be created with a digest that has extra
+ * bytes.
+ */
+ @Test
+ public final void md5IllegalDigest() {
+ final byte[] digest = getTestDigest(17);
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(DigestAlgorithm.MD5, digest));
+ }
+
+ /**
+ * Tests that SHA1 digest can be created.
+ */
+ @Test
+ public final void sha1() {
+ final byte[] digest = getTestDigest(20);
+ final Digest d = new Digest(DigestAlgorithm.SHA1, digest);
+ Assertions.assertNotNull(d);
+ }
+
+ /**
+ * Tests that SHA1 digest can be recreated from a string.
+ */
+ @Test
+ public final void testFromStringSHA1() {
+ final byte[] digestBytes = getTestDigest(20);
+ Digest digest = new Digest(DigestAlgorithm.SHA1, digestBytes);
+ String digestString = digest.toString();
+ Digest digestFromString = Digest.fromString(digestString);
+ Assertions.assertEquals(digest, digestFromString);
+ }
+
+ /**
+ * Tests that SHA1 digest cannot be created with a digest that has extra
+ * bytes.
+ */
+ @Test
+ public final void sha1IllegalDigest() {
+ final byte[] digest = getTestDigest(21);
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(DigestAlgorithm.SHA1, digest));
+ }
+
+ /**
+ * Tests that SHA256 digest can be created.
+ */
+ @Test
+ public final void sha256() {
+ final byte[] digest = getTestDigest(32);
+ final Digest d = new Digest(DigestAlgorithm.SHA256, digest);
+ Assertions.assertNotNull(d);
+ }
+
+ /**
+ * Tests that SHA256 digest can be recreated from a string.
+ */
+ @Test
+ public final void testFromStringSHA256() {
+ final byte[] digestBytes = getTestDigest(32);
+ Digest digest = new Digest(DigestAlgorithm.SHA256, digestBytes);
+ String digestString = digest.toString();
+ Digest digestFromString = Digest.fromString(digestString);
+ Assertions.assertEquals(digest, digestFromString);
+ }
+
+ /**
+ * Tests that SHA256 digest cannot be created with a digest that has extra
+ * bytes.
+ */
+ @Test
+ public final void sha256IllegalDigest() {
+ final byte[] digest = getTestDigest(33);
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(DigestAlgorithm.SHA256, digest));
+ }
+
+ /**
+ * Tests that SHA384 digest can be created.
+ */
+ @Test
+ public final void sha384() {
+ final byte[] digest = getTestDigest(48);
+ final Digest d = new Digest(DigestAlgorithm.SHA384, digest);
+ Assertions.assertNotNull(d);
+ }
+
+ /**
+ * Tests that SHA384 digest can be recreated from a string.
+ */
+ @Test
+ public final void testFromStringSHA384() {
+ final byte[] digestBytes = getTestDigest(48);
+ Digest digest = new Digest(DigestAlgorithm.SHA384, digestBytes);
+ String digestString = digest.toString();
+ Digest digestFromString = Digest.fromString(digestString);
+ Assertions.assertEquals(digest, digestFromString);
+ }
+
+ /**
+ * Tests that SHA384 digest cannot be created with a digest that has extra
+ * bytes.
+ */
+ @Test
+ public final void sha384IllegalDigest() {
+ final byte[] digest = getTestDigest(49);
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(DigestAlgorithm.SHA384, digest));
+ }
+
+ /**
+ * Tests that SHA512 digest can be created.
+ */
+ @Test
+ public final void sha512() {
+ final byte[] digest = getTestDigest(64);
+ final Digest d = new Digest(DigestAlgorithm.SHA512, digest);
+ Assertions.assertNotNull(d);
+ }
+
+ /**
+ * Tests that SHA512 digest can be recreated from a string.
+ */
+ @Test
+ public final void testFromStringSHA512() {
+ final byte[] digestBytes = getTestDigest(64);
+ Digest digest = new Digest(DigestAlgorithm.SHA512, digestBytes);
+ String digestString = digest.toString();
+ Digest digestFromString = Digest.fromString(digestString);
+ Assertions.assertEquals(digest, digestFromString);
+ }
+
+ /**
+ * Tests that SHA512 digest cannot be created with a digest that has extra
+ * bytes.
+ */
+ @Test
+ public final void sha512IllegalDigest() {
+ final byte[] digest = getTestDigest(65);
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Digest(DigestAlgorithm.SHA512, digest));
+ }
+
+ /**
+ * Tests that the correct DigestAlgorithm
is returned by
+ * {@link Digest#getAlgorithm()}.
+ */
+ @Test
+ public final void testGetAlgorithm() {
+ final Digest d = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ Assertions.assertEquals(d.getAlgorithm(), DigestAlgorithm.SHA1);
+ }
+
+ /**
+ * Tests that the bytes of the digest are created and do not affect the
+ * underlying state of the Digest
instance.
+ */
+ @Test
+ public final void testGetDigest() {
+ final Digest d = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ final byte[] digestBytes = d.getDigest();
+ final byte[] testBytes = getTestDigest(20);
+ Assertions.assertArrayEquals(digestBytes, testBytes);
+ digestBytes[0] = (byte) (digestBytes[0] + 1);
+ Assertions.assertArrayEquals(d.getDigest(), testBytes);
+ Assertions.assertFalse(Arrays.equals(d.getDigest(), digestBytes));
+ }
+
+ /**
+ * Tests that two Digest
s have equal hash code for same
+ * algorithm and digest.
+ */
+ @Test
+ public final void testHashCodeEqual() {
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ Assertions.assertEquals(d2.hashCode(), d1.hashCode());
+ }
+
+ /**
+ * Tests that two Digest
s indicate MATCH when compared.
+ */
+ @Test
+ public final void testMatchedComparison() {
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2));
+ Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1));
+ }
+
+ /**
+ * Tests that two Digest
s have unequal hash code for same
+ * digest but different algorithm.
+ */
+ @Test
+ public final void testHashCodeNotEqualAlgorithm() {
+ final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(16));
+ final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(16));
+ Assertions.assertNotEquals(d2.hashCode(), d1.hashCode());
+ }
+
+ /**
+ * Tests that two Digest
s indicate MISMATCH when compared.
+ */
+ @Test
+ public final void testMismatchAlgorithm() {
+ final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(16));
+ final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(16));
+ Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2));
+ Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1));
+ }
+
+ /**
+ * Tests that two Digest
s have unequal hash code for same
+ * algorithm but different digest.
+ */
+ @Test
+ public final void testHashCodeNotEqualDigest() {
+ final byte[] digest = getTestDigest(20);
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, digest);
+ digest[0] += 1;
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, digest);
+ Assertions.assertNotEquals(d2.hashCode(), d1.hashCode());
+ Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2));
+ }
+
+ /**
+ * Tests that two Digest
s are equal for same algorithm and
+ * digest.
+ */
+ @Test
+ public final void testEqual() {
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ Assertions.assertEquals(d2, d1);
+ }
+
+ /**
+ * Tests that two Digest
s are unequal for same digest but
+ * different algorithm.
+ */
+ @Test
+ public final void testNotEqualAlgorithm() {
+ final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(16));
+ final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(16));
+ Assertions.assertNotEquals(d2, d1);
+ }
+
+ /**
+ * Tests that two Digest
s are unequal for same algorithm but
+ * different digest.
+ */
+ @Test
+ public final void testNotEqualDigest() {
+ final byte[] digest = getTestDigest(20);
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, digest);
+ digest[0] += 1;
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, digest);
+ Assertions.assertNotEquals(d2, d1);
+ }
+
+ /**
+ * Tests that comparing a null Digest to a Digest indicates an UNKNOWN
+ * comparison type.
+ */
+ @Test
+ public final void testCompareToNull() {
+ final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(16));
+ Assertions.assertEquals(DigestComparisonResultType.UNKNOWN, d1.compare(null));
+ }
+
+ /**
+ * Tests that comparing two Digests with hashes with values of zero gives a MATCH
+ * comparison result.
+ */
+ @Test
+ public final void testCompareToDigestWithBothZeroizedHash() {
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(20));
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(20));
+ Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2));
+ Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1));
+ }
+
+ /**
+ * Tests that comparing two Digests, one with a hash of value zero, gives a MISMATCH
+ * comparison result.
+ */
+ @Test
+ public final void testCompareToDigestWithOneZeroizedHash() {
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(20));
+ Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2));
+ Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1));
+ }
+
+ /**
+ * Tests that comparing two Digests with a hash of no data gives a MATCH
+ * comparison result.
+ */
+ @Test
+ public final void testCompareToDigestWithBothEmptyHash() {
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest());
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest());
+ Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2));
+ Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1));
+ }
+
+ /**
+ * Tests that comparing two Digests, one with a hash of no data, gives a MISMATCH
+ * comparison result.
+ */
+ @Test
+ public final void testCompareToDigestWithOneEmptyHash() {
+ final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20));
+ final Digest d2 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest());
+ Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2));
+ Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1));
+ }
+
+ /**
+ * Tests that if someone tries to recreate a Digest using an invalid String, an error is thrown.
+ */
+ @Test
+ public final void testFromStringInvalid() {
+ String invalidDigestString = "SHA1 00000000000000000000";
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> Digest.fromString(invalidDigestString));
+ }
+
+ /**
+ * Get a test SHA1 digest.
+ *
+ * @return a test SHA1 digest
+ */
+ public static Digest getTestSHA1Digest() {
+ return new Digest(DigestAlgorithm.SHA1, getTestDigest(DIGEST_LENGTH_BYTES));
+ }
+
+ /**
+ * Get a test SHA1 digest filled with the given byte.
+ *
+ * @param fill the byte that will be used to fill the digest
+ * @return a test SHA1 digest with repeated entries of the given byte
+ */
+ public static Digest getTestSHA1Digest(final byte fill) {
+ return new Digest(DigestAlgorithm.SHA1, getTestDigest(DIGEST_LENGTH_BYTES, fill));
+ }
+
+ private static byte[] getTestDigest(final int count) {
+ return getTestDigest(count, (byte) 1);
+ }
+
+ private static byte[] getTestDigest(final int count, final byte fill) {
+ final byte[] ret = new byte[count];
+ Arrays.fill(ret, fill);
+ return ret;
+ }
+
+ private static byte[] getZeroValueDigest(final int count) {
+ return new byte[count];
+ }
+
+ private byte[] getEmptySHA1Digest() {
+ return DigestUtils.sha1(new byte[]{});
+ }
+}