001: // -*- Java -*-
002: //
003: // Copyright (c) 2005, Matthew J. Rutherford <rutherfo@cs.colorado.edu>
004: // Copyright (c) 2005, University of Colorado at Boulder
005: // All rights reserved.
006: //
007: // Redistribution and use in source and binary forms, with or without
008: // modification, are permitted provided that the following conditions are
009: // met:
010: //
011: // * Redistributions of source code must retain the above copyright
012: // notice, this list of conditions and the following disclaimer.
013: //
014: // * Redistributions in binary form must reproduce the above copyright
015: // notice, this list of conditions and the following disclaimer in the
016: // documentation and/or other materials provided with the distribution.
017: //
018: // * Neither the name of the University of Colorado at Boulder nor the
019: // names of its contributors may be used to endorse or promote
020: // products derived from this software without specific prior written
021: // permission.
022: //
023: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
024: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
025: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
026: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
027: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
028: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
029: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
031: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
032: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
033: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
034: //
035: package org.xbill.DNS.utils;
036:
037: import java.security.MessageDigest;
038: import java.security.NoSuchAlgorithmException;
039: import junit.framework.TestCase;
040:
041: public class HMACTest extends TestCase {
042: private static class test_data {
043: public byte[] key;
044: public byte[] data;
045: public byte[] digest;
046: }
047:
048: private static test_data[] tests;
049:
050: static {
051: // These test cases come directly from RFC 2202 (for MD5)
052:
053: tests = new test_data[7];
054:
055: for (int i = 0; i < tests.length; ++i) {
056: tests[i] = new test_data();
057: }
058:
059: // test_case = 1
060: tests[0].key = base16
061: .fromString("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
062: tests[0].data = "Hi There".getBytes();
063: tests[0].digest = base16
064: .fromString("9294727a3638bb1c13f48ef8158bfc9d");
065:
066: // test_case = 2
067: tests[1].key = "Jefe".getBytes();
068: tests[1].data = "what do ya want for nothing?".getBytes();
069: tests[1].digest = base16
070: .fromString("750c783e6ab0b503eaa86e310a5db738");
071:
072: // test_case = 3
073: tests[2].key = base16
074: .fromString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
075: tests[2].data = new byte[50]; // 0xdd repeated 50 times
076: for (int i = 0; i < tests[2].data.length; ++i) {
077: tests[2].data[i] = (byte) 0xdd;
078: }
079: tests[2].digest = base16
080: .fromString("56be34521d144c88dbb8c733f0e8b3f6");
081:
082: // test_case = 4
083: tests[3].key = base16
084: .fromString("0102030405060708090a0b0c0d0e0f10111213141516171819");
085: tests[3].data = new byte[50]; // 0xcd repeated 50 times;
086: for (int i = 0; i < tests[3].data.length; ++i) {
087: tests[3].data[i] = (byte) 0xcd;
088: }
089: tests[3].digest = base16
090: .fromString("697eaf0aca3a3aea3a75164746ffaa79");
091:
092: // test_case = 5
093: tests[4].key = base16
094: .fromString("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c");
095: tests[4].data = "Test With Truncation".getBytes();
096: tests[4].digest = base16
097: .fromString("56461ef2342edc00f9bab995690efd4c");
098:
099: // test_case = 6
100: tests[5].key = new byte[80]; // 0xaa repeated 80 times;
101: for (int i = 0; i < tests[5].key.length; ++i) {
102: tests[5].key[i] = (byte) 0xaa;
103: }
104: tests[5].data = "Test Using Larger Than Block-Size Key - Hash Key First"
105: .getBytes();
106: tests[5].digest = base16
107: .fromString("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd");
108:
109: // test_case = 7
110: tests[6].key = new byte[80]; // 0xaa repeated 80 times;
111: for (int i = 0; i < tests[6].key.length; ++i) {
112: tests[6].key[i] = (byte) 0xaa;
113: }
114: tests[6].data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
115: .getBytes();
116: tests[6].digest = base16
117: .fromString("6f630fad67cda0ee1fb1f562db3aa53e");
118: }
119:
120: public HMACTest(String name) {
121: super (name);
122: }
123:
124: private void do_test(int i, HMAC h)
125: throws CloneNotSupportedException {
126: h.update(tests[i].data, 0, tests[i].data.length);
127: byte[] out = h.sign();
128:
129: assertEquals("test=" + i, tests[i].digest.length, out.length);
130: for (int j = 0; j < out.length; ++j) {
131: assertEquals("test=" + i, tests[i].digest[j], out[j]);
132: }
133:
134: // clear and do it again to make sure verify() agrees
135: h.clear();
136: h.update(tests[i].data);
137: assertTrue(h.verify(tests[i].digest));
138:
139: // clear and do it again to make sure verify()
140: h.clear();
141: h.update(tests[i].data, 0, tests[i].data.length);
142: byte[] tmp = (byte[]) tests[i].digest.clone();
143: tmp[tmp.length / 2] = (byte) 0xAB;
144: assertFalse(h.verify(tmp));
145: }
146:
147: public void test_ctor_digest_key() throws NoSuchAlgorithmException,
148: CloneNotSupportedException {
149: for (int i = 0; i < tests.length; ++i) {
150: MessageDigest md = MessageDigest.getInstance("md5");
151: HMAC h = new HMAC(md, tests[i].key);
152: do_test(i, h);
153: }
154: }
155:
156: public void test_ctor_digestName_key()
157: throws NoSuchAlgorithmException, CloneNotSupportedException {
158: for (int i = 0; i < tests.length; ++i) {
159: HMAC h = new HMAC("md5", tests[i].key);
160: do_test(i, h);
161: }
162: }
163:
164: public void test_ctor_digestName_key_invalid() {
165: try {
166: new HMAC("no name", new byte[0]);
167: fail("IllegalArgumentException not thrown");
168: } catch (IllegalArgumentException e) {
169: }
170: }
171: }
|