001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.security.tests.java.security;
019:
020: import java.io.ByteArrayOutputStream;
021: import java.io.DataOutputStream;
022: import java.io.IOException;
023: import java.security.DigestException;
024: import java.security.MessageDigest;
025: import java.security.NoSuchAlgorithmException;
026: import java.security.NoSuchProviderException;
027: import java.security.Provider;
028: import java.security.Security;
029: import java.util.Arrays;
030: import java.util.Enumeration;
031: import java.util.Vector;
032:
033: public class MessageDigest2Test extends junit.framework.TestCase {
034:
035: private static final String MESSAGEDIGEST_ID = "MessageDigest.";
036:
037: private String[] digestAlgs = null;
038:
039: private String providerName = null;
040:
041: private static final byte[] AR1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
042:
043: private static final byte[] AR2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
044:
045: private static final String MESSAGE = "abc";
046:
047: private static final byte[] MESSAGE_DIGEST = { -87, -103, 62, 54,
048: 71, 6, -127, 106, -70, 62, 37, 113, 120, 80, -62, 108,
049: -100, -48, -40, -99, };
050:
051: private static final byte[] MESSAGE_DIGEST_63_As = { 3, -16, -97,
052: 91, 21, -118, 122, -116, -38, -39, 32, -67, -36, 41, -72,
053: 28, 24, -91, 81, -11, };
054:
055: private static final byte[] MESSAGE_DIGEST_64_As = { 0, -104, -70,
056: -126, 75, 92, 22, 66, 123, -41, -95, 18, 42, 90, 68, 42,
057: 37, -20, 100, 77, };
058:
059: private static final byte[] MESSAGE_DIGEST_65_As = { 17, 101, 83,
060: 38, -57, 8, -41, 3, 25, -66, 38, 16, -24, -91, 125, -102,
061: 91, -107, -99, 59, };
062:
063: /**
064: * @tests java.security.MessageDigest#clone()
065: */
066: public void test_clone() {
067: for (int i = 0; i < digestAlgs.length; i++) {
068: try {
069: MessageDigest d1 = MessageDigest.getInstance(
070: digestAlgs[i], providerName);
071: for (byte b = 0; b < 84; b++) {
072: d1.update(b);
073: }
074:
075: MessageDigest d2 = (MessageDigest) d1.clone();
076: d1.update((byte) 1);
077: d2.update((byte) 1);
078:
079: assertTrue(
080: "cloned hash differs from original for algorithm "
081: + digestAlgs[i], MessageDigest.isEqual(
082: d1.digest(), d2.digest()));
083: } catch (CloneNotSupportedException e) {
084: // Expected - a Signature may not be cloneable
085: } catch (NoSuchAlgorithmException e) {
086: fail("getInstance did not find algorithm "
087: + digestAlgs[i]);
088: } catch (NoSuchProviderException e) {
089: fail("getInstance did not find provider "
090: + providerName);
091: }
092: }
093: }
094:
095: private static final byte[] SHA_DATA_2 = { 70, -54, 124, 120, -29,
096: 57, 56, 119, -108, -54, -97, -76, -97, -50, -63, -73, 2,
097: 85, -53, -79, };
098:
099: private void testSerializationSHA_DATA_2(MessageDigest sha) {
100: try {
101: sha.reset();
102: ByteArrayOutputStream out = new ByteArrayOutputStream();
103: DataOutputStream output = new DataOutputStream(out);
104: // -----------------------------------------------------------------------
105:
106: // Made up data
107: output
108: .writeUTF("tests.api.java.security.MessageDigestTest$InitializerFieldsTest3");
109: output.writeInt(0); // class modifiers
110: output.writeUTF("java.io.Serializable"); // interfaces
111:
112: // Fields
113: output.writeUTF("sub_toBeNotSerialized"); // name
114: output.writeInt(9); // modifiers
115: output.writeUTF("Ljava/lang/String;"); // signature
116:
117: output.writeUTF("sub_toBeNotSerialized2"); // name
118: output.writeInt(9); // modifiers
119: output.writeUTF("Ljava/lang/String;"); // signature
120:
121: output.writeUTF("sub_toBeSerialized"); // name
122: output.writeInt(1); // modifiers
123: output.writeUTF("Ljava/lang/String;"); // signature
124:
125: output.writeUTF("sub_toBeSerialized3"); // name
126: output.writeInt(1); // modifiers
127: output.writeUTF("Ljava/lang/String;"); // signature
128:
129: output.writeUTF("sub_toBeSerialized4"); // name
130: output.writeInt(1); // modifiers
131: output.writeUTF("Ljava/lang/String;"); // signature
132:
133: output.writeUTF("sub_toBeSerialized5"); // name
134: output.writeInt(1); // modifiers
135: output.writeUTF("Ljava/lang/String;"); // signature
136:
137: // clinit
138: output.writeUTF("<clinit>"); // name
139: output.writeInt(8); // modifiers
140: output.writeUTF("()V"); // signature
141:
142: // constructors
143: output.writeUTF("<init>"); // name
144: output.writeInt(0); // modifiers
145: output.writeUTF("()V"); // signature
146:
147: // methods
148: output.writeUTF("equals"); // name
149: output.writeInt(1); // modifiers
150: output.writeUTF("(Ljava.lang.Object;)Z"); // signature
151:
152: // -----------------------------------------------------------------------
153:
154: output.flush();
155:
156: byte[] data = out.toByteArray();
157: byte[] hash = sha.digest(data);
158: assertTrue("SHA_DATA_2 NOT ok", Arrays.equals(hash,
159: SHA_DATA_2));
160: } catch (IOException e) {
161: fail("SHA_DATA_2 NOT ok");
162: }
163: }
164:
165: private static final byte[] SHA_DATA_1 = { 90, 36, 111, 106, -32,
166: 38, 4, 126, 21, -51, 107, 45, -64, -68, -109, 112, -31,
167: -46, 34, 115, };
168:
169: private void testSerializationSHA_DATA_1(MessageDigest sha) {
170: try {
171: sha.reset();
172: ByteArrayOutputStream out = new ByteArrayOutputStream();
173: DataOutputStream output = new DataOutputStream(out);
174: // -----------------------------------------------------------------------
175:
176: // Made up data
177: output
178: .writeUTF("tests.api.java.security.MessageDigestTest$OptionalDataNotRead");
179: // name
180: output.writeInt(0); // class modifiers
181: output.writeUTF("java.io.Serializable"); // interfaces
182:
183: // Fields
184: output.writeUTF("class$0"); // name
185: output.writeInt(8); // modifiers
186: output.writeUTF("Ljava/lang/Class;"); // signature
187:
188: output.writeUTF("field1"); // name
189: output.writeInt(2); // modifiers
190: output.writeUTF("I"); // signature
191:
192: output.writeUTF("field2"); // name
193: output.writeInt(2); // modifiers
194: output.writeUTF("I"); // signature
195:
196: // clinit
197: output.writeUTF("<clinit>"); // name
198: output.writeInt(8); // modifiers
199: output.writeUTF("()V"); // signature
200:
201: // constructors
202: output.writeUTF("<init>"); // name
203: output.writeInt(1); // modifiers
204: output.writeUTF("()V"); // signature
205: // -----------------------------------------------------------------------
206:
207: output.flush();
208: byte[] data = out.toByteArray();
209: byte[] hash = sha.digest(data);
210: assertTrue("SHA_DATA_1 NOT ok", Arrays.equals(hash,
211: SHA_DATA_1));
212: } catch (IOException e) {
213: fail("SHA_DATA_1 NOT ok");
214: }
215: }
216:
217: /**
218: * @tests java.security.MessageDigest#digest()
219: */
220: public void test_digest() {
221: MessageDigest sha = null;
222: try {
223: sha = MessageDigest.getInstance("SHA");
224: assertNotNull(sha);
225: } catch (NoSuchAlgorithmException e) {
226: fail("getInstance did not find algorithm");
227: }
228: sha.update(MESSAGE.getBytes());
229: byte[] digest = sha.digest();
230: assertTrue("bug in SHA", MessageDigest.isEqual(digest,
231: MESSAGE_DIGEST));
232:
233: sha.reset();
234: for (int i = 0; i < 63; i++) {
235: // just under buffer capacity
236: sha.update((byte) 'a');
237: }
238: digest = sha.digest();
239: assertTrue("bug in SHA", MessageDigest.isEqual(digest,
240: MESSAGE_DIGEST_63_As));
241:
242: sha.reset();
243: for (int i = 0; i < 64; i++) {
244: // exact SHA buffer capacity
245: sha.update((byte) 'a');
246: }
247: digest = sha.digest();
248: assertTrue("bug in SHA", MessageDigest.isEqual(digest,
249: MESSAGE_DIGEST_64_As));
250:
251: sha.reset();
252: for (int i = 0; i < 65; i++) {
253: // just above SHA buffer capacity
254: sha.update((byte) 'a');
255: }
256: digest = sha.digest();
257: assertTrue("bug in SHA", MessageDigest.isEqual(digest,
258: MESSAGE_DIGEST_65_As));
259:
260: testSerializationSHA_DATA_1(sha);
261: testSerializationSHA_DATA_2(sha);
262: }
263:
264: /**
265: * @tests java.security.MessageDigest#digest(byte[])
266: */
267: public void test_digest$B() {
268: for (int i = 0; i < digestAlgs.length; i++) {
269: try {
270: MessageDigest digest = MessageDigest.getInstance(
271: digestAlgs[i], providerName);
272: assertNotNull(digest);
273: digest.digest(AR1);
274: } catch (NoSuchAlgorithmException e) {
275: fail("getInstance did not find algorithm "
276: + digestAlgs[i]);
277: } catch (NoSuchProviderException e) {
278: fail("getInstance did not find provider "
279: + providerName);
280: }
281: }
282: }
283:
284: /**
285: * @tests java.security.MessageDigest#digest(byte[], int, int)
286: */
287: public void test_digest$BII() {
288: for (int i = 0; i < digestAlgs.length; i++) {
289: try {
290: MessageDigest digest = MessageDigest.getInstance(
291: digestAlgs[i], providerName);
292: assertNotNull(digest);
293: int len = digest.getDigestLength();
294: byte[] digestBytes = new byte[len];
295: digest.digest(digestBytes, 0, digestBytes.length);
296: } catch (NoSuchAlgorithmException e) {
297: fail("getInstance did not find algorithm "
298: + digestAlgs[i]);
299: } catch (NoSuchProviderException e) {
300: fail("getInstance did not find provider "
301: + providerName);
302: } catch (DigestException e) {
303: fail("digest caused exception for algorithm "
304: + digestAlgs[i] + " : " + e);
305: }
306: }
307: try {
308: MessageDigest.getInstance("SHA").digest(new byte[] {},
309: Integer.MAX_VALUE, 755);
310: } catch (NoSuchAlgorithmException e) {
311: //allowed
312: } catch (DigestException e) {
313: //allowed
314: } catch (IllegalArgumentException e) {
315: //expected
316: }
317: }
318:
319: /**
320: * @tests java.security.MessageDigest#update(byte[], int, int)
321: */
322: public void test_update$BII() {
323: try {
324: MessageDigest.getInstance("SHA").update(new byte[] {},
325: Integer.MAX_VALUE, Integer.MAX_VALUE);
326: } catch (NoSuchAlgorithmException e) {
327: //allowed
328: } catch (IllegalArgumentException e) {
329: //expected
330: }
331: }
332:
333: /**
334: * @tests java.security.MessageDigest#getAlgorithm()
335: */
336: public void test_getAlgorithm() {
337: for (int i = 0; i < digestAlgs.length; i++) {
338: try {
339: String alg = MessageDigest.getInstance(digestAlgs[i],
340: providerName).getAlgorithm();
341: assertTrue("getAlgorithm ok", alg.equals(digestAlgs[i]));
342: } catch (NoSuchAlgorithmException e) {
343: fail("getInstance did not find algorithm "
344: + digestAlgs[i]);
345: } catch (NoSuchProviderException e) {
346: fail("getInstance did not find provider "
347: + providerName);
348: }
349: }
350: }
351:
352: /**
353: * @tests java.security.MessageDigest#getDigestLength()
354: */
355: public void test_getDigestLength() {
356: for (int i = 0; i < digestAlgs.length; i++) {
357: try {
358: int len = MessageDigest.getInstance(digestAlgs[i],
359: providerName).getDigestLength();
360: assertTrue("length not ok", len > 0);
361: } catch (NoSuchAlgorithmException e) {
362: fail("getInstance did not find algorithm "
363: + digestAlgs[i]);
364: } catch (NoSuchProviderException e) {
365: fail("getInstance did not find provider "
366: + providerName);
367: }
368: }// end for
369: }
370:
371: /**
372: * @tests java.security.MessageDigest#getInstance(java.lang.String)
373: */
374: public void test_getInstanceLjava_lang_String() {
375: for (int i = 0; i < digestAlgs.length; i++) {
376: try {
377: MessageDigest.getInstance(digestAlgs[i]);
378: } catch (NoSuchAlgorithmException e) {
379: fail("getInstance did not find algorithm "
380: + digestAlgs[i]);
381: }
382: }
383: }
384:
385: /**
386: * @tests java.security.MessageDigest#getInstance(java.lang.String,
387: * java.lang.String)
388: */
389: public void test_getInstanceLjava_lang_StringLjava_lang_String() {
390: for (int i = 0; i < digestAlgs.length; i++) {
391: try {
392: MessageDigest.getInstance(digestAlgs[i], providerName);
393: } catch (NoSuchAlgorithmException e) {
394: fail("getInstance did not find algorithm "
395: + digestAlgs[i]);
396: } catch (NoSuchProviderException e) {
397: fail("getInstance did not find provider "
398: + providerName);
399: }
400: }
401: }
402:
403: /**
404: * @tests java.security.MessageDigest#getProvider()
405: */
406: public void test_getProvider() {
407: for (int i = 0; i < digestAlgs.length; i++) {
408: try {
409: Provider p = MessageDigest.getInstance(digestAlgs[i],
410: providerName).getProvider();
411: assertNotNull("provider is null", p);
412: } catch (NoSuchAlgorithmException e) {
413: fail("getInstance did not find algorithm "
414: + digestAlgs[i]);
415: } catch (NoSuchProviderException e) {
416: fail("getInstance did not find provider "
417: + providerName);
418: }
419: }
420: }
421:
422: /**
423: * @tests java.security.MessageDigest#isEqual(byte[], byte[])
424: */
425: public void test_isEqual$B$B() {
426: assertTrue("isEqual is not correct", MessageDigest.isEqual(AR1,
427: AR2));
428: }
429:
430: /**
431: * @tests java.security.MessageDigest#toString()
432: */
433: public void test_toString() {
434: try {
435: String str = MessageDigest.getInstance("SHA").toString();
436: assertNotNull("toString is null", str);
437: } catch (NoSuchAlgorithmException e) {
438: fail("getInstance did not find algorithm");
439: }
440: }
441:
442: protected void setUp() {
443: if (digestAlgs == null) {
444: Provider[] providers = Security
445: .getProviders("MessageDigest.SHA");
446: if (providers == null) {
447: fail("No providers available for test");
448: }
449:
450: // Arbitrarily select the first available provider
451: providerName = providers[0].getName();
452: digestAlgs = getDigestAlgorithms(providerName);
453: if (digestAlgs == null || digestAlgs.length == 0) {
454: fail("No digest algorithms were found");
455: }
456: }
457: }
458:
459: /*
460: * Returns the digest algorithms that the given provider supports.
461: */
462: private String[] getDigestAlgorithms(String providerName) {
463: Vector algs = new Vector();
464:
465: Provider provider = Security.getProvider(providerName);
466: if (provider == null)
467: return new String[0];
468: Enumeration e = provider.keys();
469: while (e.hasMoreElements()) {
470: String algorithm = (String) e.nextElement();
471: if (algorithm.startsWith(MESSAGEDIGEST_ID)
472: && !algorithm.contains(" ")) {
473: algs.addElement(algorithm.substring(MESSAGEDIGEST_ID
474: .length()));
475: }
476: }// end while
477:
478: return (String[]) algs.toArray(new String[algs.size()]);
479: }
480: }
|