package com.sun.midp.crypto;
import gnu.testlet.TestHarness;
import gnu.testlet.Testlet;
public class TestMD5 implements Testlet {
public int getExpectedPass() { return 13; }
public int getExpectedFail() { return 0; }
public int getExpectedKnownFail() { return 0; }
public static byte[] hexToBytes(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public void test(TestHarness th) {
MD5 md5 = new MD5();
th.check(md5.getAlgorithm(), "MD5");
th.check(md5.getDigestLength(), 16);
byte[] buf = new byte[16];
try {
md5.digest(buf, 0, 16);
} catch (DigestException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
}
th.check(Util.hexEncode(buf), "d41d8cd98f00b204e9800998ecf8427e");
md5.reset();
String part1 = "a";
md5.update(part1.getBytes(), 0, part1.length());
try {
md5.digest(buf, 0, 16);
} catch (DigestException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
}
th.check(Util.hexEncode(buf), "0cc175b9c0f1b6a831c399e269772661");
md5.reset();
md5.update(part1.getBytes(), 0, part1.length());
String part2 = "NOb";
md5.update(part2.getBytes(), 2, part2.length()-2);
String part3 = "NOcNO";
md5.update(part3.getBytes(), 2, part3.length()-4);
try {
md5.digest(buf, 0, 16);
} catch (DigestException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
}
th.check(Util.hexEncode(buf), "900150983cd24fb0d6963f7d28e17f72");
// Calculate another hash without calling sha.reset() (sha.digest should reset automatically)
String longStr = "12345678901234567890123456789012345678901234567890123456789012345678901234567890";
md5.update(longStr.getBytes(), 0, longStr.length());
try {
md5.digest(buf, 0, 16);
} catch (DigestException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
}
th.check(Util.hexEncode(buf), "57edf4a22be3c955ac49da2e2107b67a");
byte[] shortBuf = new byte[15];
try {
md5.digest(buf, 0, 15);
th.fail("Should've raised an exception");
} catch (DigestException ex) {
th.check(true, "Exception raised");
}
md5.reset();
// Ensure we can calculate two digests simultaneously.
md5.update(part1.getBytes(), 0, part1.length());
MD5 md52 = new MD5();
md52.update(part2.getBytes(), 0, part2.length());
byte[] buf2 = new byte[16];
try {
md5.digest(buf, 0, 16);
md52.digest(buf2, 0, 16);
} catch (DigestException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
}
th.check(Util.hexEncode(buf), "0cc175b9c0f1b6a831c399e269772661");
th.check(Util.hexEncode(buf2), "40309ea6baa09db375e49aa5edcb40a6");
md5.reset();
md52.reset();
md5.update(part1.getBytes(), 0, part1.length());
md5.reset();
md5.update(part2.getBytes(), 0, part2.length());
try {
md5.digest(buf, 0, 16);
} catch (DigestException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
}
th.check(Util.hexEncode(buf), "40309ea6baa09db375e49aa5edcb40a6");
byte[] bufMsg = hexToBytes("308203c6a00302010202020301300d06092a864886f70d01010505003063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479301e170d3036313131363031353433375a170d3236313131363031353433375a3081ca310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e31333031060355040b132a687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72793130302e06035504031327476f204461646479205365637572652043657274696669636174696f6e20417574686f726974793111300f06035504051308303739363932383730820122300d06092a864886f70d01010105000382010f003082010a0282010100c42dd5158c9c264cec3235eb5fb859015aa66181593b7063abe3dc3dc72ab8c933d379e43aed3c3023848eb33014b6b287c33d9554049edf99dd0b251e21de65297e35a8a954ebf6f73239d4265595adeffbfe5886d79ef4008d8c2a0cbd4204cea73f04f6ee80f2aaef52a16966dabe1aad5dda2c66ea1a6bbbe51a514a002f48c79875d8b929c8eef8666d0a9cb3f3fc787ca2f8a3f2b5c3f3b97a91c1a7e6252e9ca8ed12656e6af6124453703095c39c2b582b3d08744af2be51b0bf87d04c27586bb535c59daf1731f80b8feead813605890898cf3aaf2587c049eaa7fd67f7458e97cc1439e23685b57e1a37fd16f671119a743016fe1394a33f840d4f0203010001a38201323082012e301d0603551d0e04160414fdac6132936c45d6e2ee855f9abae7769968cce7301f0603551d23041830168014d2c4b0d291d44c1171b361cb3da1fedda86ad4e330120603551d130101ff040830060101ff020100303306082b0601050507010104273025302306082b060105050730018617687474703a2f2f6f6373702e676f64616464792e636f6d30460603551d1f043f303d303ba039a0378635687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f6764726f6f742e63726c304b0603551d200444304230400604551d20003038303606082b06010505070201162a687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f7279300e0603551d0f0101ff040403020106");
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
return;
}
md.update(bufMsg, 0, bufMsg.length);
try {
md.digest(buf, 0, buf.length);
} catch (DigestException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
}
th.check(Util.hexEncode(buf), "3fd0fac5027a9cd891c2dc778c88167a");
try {
this.testClone(th);
} catch (DigestException e) {
th.fail("Unexpected exception: " + e);
e.printStackTrace();
}
}
private void testClone(TestHarness th) throws DigestException {
MD5 hasher1 = new MD5();
byte[] buf1 = new byte[16];
String partA = "a";
hasher1.update(partA.getBytes(), 0, partA.length());
MD5 hasher2 = (MD5)hasher1.clone();
byte[] buf2 = new byte[16];
String partB = "b";
hasher1.update(partB.getBytes(), 0, partB.length());
String partC = "c";
hasher2.update(partC.getBytes(), 0, partC.length());
// hasher1 should be unaffected by the update to hasher2.
// It should hash "ab", the concatenation of partA and partB.
hasher1.digest(buf1, 0, 16);
th.check(Util.hexEncode(buf1), "187ef4436122d1cc2f40dc2b92f0eba0");
// hasher2 should be unaffected by the update to hasher1.
// It should hash "ac", the concatenation of partA and partC.
hasher2.digest(buf2, 0, 16);
th.check(Util.hexEncode(buf2), "e2075474294983e013ee4dd2201c7a73");
hasher1.reset();
hasher2.reset();
}
}