package com.sun.midp.crypto; import gnu.testlet.TestHarness; import gnu.testlet.Testlet; public class TestSHA 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) { SHA sha = new SHA(); th.check(sha.getAlgorithm(), "SHA-1"); th.check(sha.getDigestLength(), 20); byte[] buf = new byte[20]; try { sha.digest(buf, 0, 20); } catch (DigestException e) { th.fail("Unexpected exception: " + e); e.printStackTrace(); } th.check(Util.hexEncode(buf), "da39a3ee5e6b4b0d3255bfef95601890afd80709"); sha.reset(); String part1 = "a"; sha.update(part1.getBytes(), 0, part1.length()); try { sha.digest(buf, 0, 20); } catch (DigestException e) { th.fail("Unexpected exception: " + e); e.printStackTrace(); } th.check(Util.hexEncode(buf), "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"); sha.reset(); sha.update(part1.getBytes(), 0, part1.length()); String part2 = "NOb"; sha.update(part2.getBytes(), 2, part2.length()-2); String part3 = "NOcNO"; sha.update(part3.getBytes(), 2, part3.length()-4); try { sha.digest(buf, 0, 20); } catch (DigestException e) { th.fail("Unexpected exception: " + e); e.printStackTrace(); } th.check(Util.hexEncode(buf), "a9993e364706816aba3e25717850c26c9cd0d89d"); // Calculate another hash without calling sha.reset() (sha.digest should reset automatically) String longStr = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"; sha.update(longStr.getBytes(), 0, longStr.length()); try { sha.digest(buf, 0, 20); } catch (DigestException e) { th.fail("Unexpected exception: " + e); e.printStackTrace(); } th.check(Util.hexEncode(buf), "50abf5706a150990a08b2c5ea40fa0e585554732"); byte[] shortBuf = new byte[15]; try { sha.digest(buf, 0, 15); th.fail("Should've raised an exception"); } catch (DigestException ex) { th.check(true, "Exception raised"); } sha.reset(); // Ensure we can calculate two digests simultaneously. sha.update(part1.getBytes(), 0, part1.length()); SHA sha2 = new SHA(); sha2.update(part2.getBytes(), 0, part2.length()); byte[] buf2 = new byte[20]; try { sha.digest(buf, 0, 20); sha2.digest(buf2, 0, 20); } catch (DigestException e) { th.fail("Unexpected exception: " + e); e.printStackTrace(); } th.check(Util.hexEncode(buf), "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"); th.check(Util.hexEncode(buf2), "5bd138dc4bccbc9526f6575c21d5e66450cd257f"); sha.reset(); sha2.reset(); sha.update(part1.getBytes(), 0, part1.length()); sha.reset(); sha.update(part2.getBytes(), 0, part2.length()); try { sha.digest(buf, 0, 20); } catch (DigestException e) { th.fail("Unexpected exception: " + e); e.printStackTrace(); } th.check(Util.hexEncode(buf), "5bd138dc4bccbc9526f6575c21d5e66450cd257f"); sha.reset(); byte[] bufMsg = hexToBytes("308203c6a00302010202020301300d06092a864886f70d01010505003063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479301e170d3036313131363031353433375a170d3236313131363031353433375a3081ca310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e31333031060355040b132a687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72793130302e06035504031327476f204461646479205365637572652043657274696669636174696f6e20417574686f726974793111300f06035504051308303739363932383730820122300d06092a864886f70d01010105000382010f003082010a0282010100c42dd5158c9c264cec3235eb5fb859015aa66181593b7063abe3dc3dc72ab8c933d379e43aed3c3023848eb33014b6b287c33d9554049edf99dd0b251e21de65297e35a8a954ebf6f73239d4265595adeffbfe5886d79ef4008d8c2a0cbd4204cea73f04f6ee80f2aaef52a16966dabe1aad5dda2c66ea1a6bbbe51a514a002f48c79875d8b929c8eef8666d0a9cb3f3fc787ca2f8a3f2b5c3f3b97a91c1a7e6252e9ca8ed12656e6af6124453703095c39c2b582b3d08744af2be51b0bf87d04c27586bb535c59daf1731f80b8feead813605890898cf3aaf2587c049eaa7fd67f7458e97cc1439e23685b57e1a37fd16f671119a743016fe1394a33f840d4f0203010001a38201323082012e301d0603551d0e04160414fdac6132936c45d6e2ee855f9abae7769968cce7301f0603551d23041830168014d2c4b0d291d44c1171b361cb3da1fedda86ad4e330120603551d130101ff040830060101ff020100303306082b0601050507010104273025302306082b060105050730018617687474703a2f2f6f6373702e676f64616464792e636f6d30460603551d1f043f303d303ba039a0378635687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f6764726f6f742e63726c304b0603551d200444304230400604551d20003038303606082b06010505070201162a687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f7279300e0603551d0f0101ff040403020106"); MessageDigest md; try { md = MessageDigest.getInstance("SHA-1"); } 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), "db433834d80013ac248c21b354b482890a8f9fc2"); try { this.testClone(th); } catch (DigestException e) { th.fail("Unexpected exception: " + e); e.printStackTrace(); } } private void testClone(TestHarness th) throws DigestException { SHA sha1 = new SHA(); byte[] buf1 = new byte[20]; String partA = "a"; sha1.update(partA.getBytes(), 0, partA.length()); SHA sha2 = (SHA)sha1.clone(); byte[] buf2 = new byte[20]; String partB = "b"; sha1.update(partB.getBytes(), 0, partB.length()); String partC = "c"; sha2.update(partC.getBytes(), 0, partC.length()); // sha1 should be unaffected by the update to sha2. // It should hash "ab", the concatenation of partA and partB. sha1.digest(buf1, 0, 20); th.check(Util.hexEncode(buf1), "da23614e02469a0d7c7bd1bdab5c9c474b1904dc"); // sha2 should be unaffected by the update to sha1. // It should hash "ac", the concatenation of partA and partC. sha2.digest(buf2, 0, 20); th.check(Util.hexEncode(buf2), "0c11d463c749db5838e2c0e489bf869d531e5403"); sha1.reset(); sha2.reset(); } }