1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18/**
19* @author Vera Y. Petrashkova
20* @version $Revision$
21*/
22
23package org.apache.harmony.crypto.tests.javax.crypto;
24
25import java.nio.ByteBuffer;
26import java.security.InvalidAlgorithmParameterException;
27import java.security.InvalidKeyException;
28import java.security.NoSuchAlgorithmException;
29import java.security.NoSuchProviderException;
30import java.security.PrivateKey;
31import java.security.Provider;
32import java.security.Security;
33import java.security.spec.PSSParameterSpec;
34import java.util.ArrayList;
35import java.util.Arrays;
36import javax.crypto.Mac;
37import javax.crypto.MacSpi;
38import javax.crypto.SecretKey;
39import javax.crypto.ShortBufferException;
40import javax.crypto.spec.DHGenParameterSpec;
41import javax.crypto.spec.SecretKeySpec;
42import org.apache.harmony.crypto.tests.support.MyMacSpi;
43import org.apache.harmony.security.tests.support.SpiEngUtils;
44import junit.framework.TestCase;
45import junit.framework.Test;
46import junit.framework.TestSuite;
47import libcore.java.security.StandardNames;
48import libcore.javax.crypto.MockKey;
49import libcore.javax.crypto.MockKey2;
50
51/**
52 * Tests for Mac class constructors and methods
53 *
54 */
55public class MacTest extends TestCase {
56
57    public static final String srvMac = "Mac";
58
59    private static String defaultAlgorithm = null;
60
61    private static String defaultProviderName = null;
62
63    private static Provider defaultProvider = null;
64
65    private static boolean DEFSupported = false;
66
67    private static final String NotSupportedMsg = "There is no suitable provider for Mac";
68
69    private static final String[] invalidValues = SpiEngUtils.invalidValues;
70
71    private static String[] validValues = new String[3];
72
73    public static final String validAlgorithmsMac [] =
74        {"HmacSHA1", "HmacMD5", "HmacSHA224", "HmacSHA256", "HmacSHA384", "HmacSHA512"};
75
76
77    static {
78        for (int i = 0; i < validAlgorithmsMac.length; i++) {
79            defaultProvider = SpiEngUtils.isSupport(validAlgorithmsMac[i],
80                    srvMac);
81            DEFSupported = (defaultProvider != null);
82            if (DEFSupported) {
83                defaultAlgorithm = validAlgorithmsMac[i];
84                defaultProviderName = defaultProvider.getName();
85                validValues[0] = defaultAlgorithm;
86                validValues[1] = defaultAlgorithm.toUpperCase();
87                validValues[2] = defaultAlgorithm.toLowerCase();
88                break;
89            }
90        }
91    }
92
93    private Mac[] createMacs() throws Exception {
94        if (!DEFSupported) {
95            fail(NotSupportedMsg);
96            return null;
97        }
98        ArrayList<Mac> macList = new ArrayList<Mac>();
99        macList.add(Mac.getInstance(defaultAlgorithm));
100        macList.add(Mac.getInstance(defaultAlgorithm, defaultProvider));
101        macList.add(Mac.getInstance(defaultAlgorithm, defaultProviderName));
102        for (Provider p : Security.getProviders("Mac." + defaultAlgorithm)) {
103            macList.add(Mac.getInstance(defaultAlgorithm, p));
104        }
105        return macList.toArray(new Mac[macList.size()]);
106    }
107
108    /**
109     * Test for <code>getInstance(String algorithm)</code> method
110     * Assertion:
111     * throws NullPointerException when algorithm is null
112     * throws NoSuchAlgorithmException when algorithm is not available
113     */
114    public void testMac01() {
115        try {
116            Mac.getInstance(null);
117            fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
118        } catch (NullPointerException e) {
119        } catch (NoSuchAlgorithmException e) {
120        }
121        for (int i = 0; i < invalidValues.length; i++) {
122            try {
123                Mac.getInstance(invalidValues[i]);
124                fail("NoSuchAlgorithmException must be thrown when algorithm is not available: "
125                        .concat(invalidValues[i]));
126            } catch (NoSuchAlgorithmException e) {
127            }
128        }
129    }
130
131    /**
132     * Test for <code>getInstance(String algorithm)</code> method
133     * Assertion: returns Mac object
134     */
135    public void testMac02() throws NoSuchAlgorithmException {
136        if (!DEFSupported) {
137            fail(NotSupportedMsg);
138            return;
139        }
140        Mac mac;
141        for (int i = 0; i < validValues.length; i++) {
142            mac = Mac.getInstance(validValues[i]);
143            assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
144        }
145    }
146    /**
147     * Test for <code>getInstance(String algorithm, String provider)</code> method
148     * Assertion:
149     * throws IllegalArgumentException when provider is null or empty
150     * throws NoSuchProviderException when provider is not available
151     */
152    public void testMac03() throws NoSuchAlgorithmException, NoSuchProviderException {
153        if (!DEFSupported) {
154            fail(NotSupportedMsg);
155            return;
156        }
157        String provider = null;
158        for (int i = 0; i < validValues.length; i++) {
159            try {
160                Mac.getInstance(validValues[i], provider);
161                fail("IllegalArgumentException must be thrown when provider is null");
162            } catch (IllegalArgumentException e) {
163            }
164            try {
165                Mac.getInstance(validValues[i], "");
166                fail("IllegalArgumentException must be thrown when provider is empty");
167            } catch (IllegalArgumentException e) {
168            }
169            for (int j = 1; j < invalidValues.length; j++) {
170                try {
171                    Mac.getInstance(validValues[i], invalidValues[j]);
172                    fail("NoSuchProviderException must be thrown (algorithm: "
173                            .concat(validValues[i]).concat(" provider: ")
174                            .concat(invalidValues[j]).concat(")"));
175                } catch (NoSuchProviderException e) {
176                }
177            }
178        }
179    }
180
181    /**
182     * Test for <code>getInstance(String algorithm, String provider)</code> method
183     * Assertion:
184     * throws NullPointerException when algorithm is null
185     * throws NoSuchAlgorithmException when algorithm is not available
186     */
187    public void testMac04() throws NoSuchAlgorithmException,
188            IllegalArgumentException, NoSuchProviderException {
189        if (!DEFSupported) {
190            fail(NotSupportedMsg);
191            return;
192        }
193        try {
194            Mac.getInstance(null, defaultProviderName);
195            fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
196        } catch (NullPointerException e) {
197        } catch (NoSuchAlgorithmException e) {
198        }
199        for (int i = 0; i < invalidValues.length; i++) {
200            try {
201                Mac.getInstance(invalidValues[i], defaultProviderName);
202                fail("NoSuchAlgorithmException must be throws when algorithm is not available: "
203                        .concat(invalidValues[i]));
204            } catch( NoSuchAlgorithmException e) {
205            }
206        }
207    }
208    /**
209     * Test for <code>getInstance(String algorithm, String provider)</code> method
210     * Assertion: returns Mac object
211     */
212    public void testMac05() throws NoSuchAlgorithmException, NoSuchProviderException,
213            IllegalArgumentException {
214        if (!DEFSupported) {
215            fail(NotSupportedMsg);
216            return;
217        }
218        Mac mac;
219        for (int i = 0; i < validValues.length; i++) {
220            mac = Mac.getInstance(validValues[i], defaultProviderName);
221            assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
222            assertEquals("Incorrect provider", mac.getProvider().getName(),
223                    defaultProviderName);
224        }
225    }
226
227    /**
228     * Test for <code>getInstance(String algorithm, Provider provider)</code> method
229     * Assertion: throws IllegalArgumentException when provider is null
230     */
231    public void testMac06() throws NoSuchAlgorithmException, NoSuchProviderException {
232        if (!DEFSupported) {
233            fail(NotSupportedMsg);
234            return;
235        }
236        Provider provider = null;
237        for (int i = 0; i < validValues.length; i++) {
238            try {
239                Mac.getInstance(validValues[i], provider);
240                fail("IllegalArgumentException must be thrown when provider is null");
241            } catch (IllegalArgumentException e) {
242            }
243        }
244    }
245    /**
246     * Test for <code>getInstance(String algorithm, Provider provider)</code> method
247     * Assertion:
248     * throws NullPointerException when algorithm is null
249     * throws NoSuchAlgorithmException when algorithm is not available
250     */
251    public void testMac07() throws NoSuchAlgorithmException,
252            NoSuchProviderException, IllegalArgumentException {
253        if (!DEFSupported) {
254            fail(NotSupportedMsg);
255            return;
256        }
257        try {
258            Mac.getInstance(null, defaultProvider);
259            fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
260        } catch (NullPointerException e) {
261        } catch (NoSuchAlgorithmException e) {
262        }
263        for (int i = 0; i < invalidValues.length; i++) {
264            try {
265                Mac.getInstance(invalidValues[i], defaultProvider);
266                fail("NoSuchAlgorithmException must be thrown when algorithm is not available: "
267                        .concat(invalidValues[i]));
268            } catch (NoSuchAlgorithmException e) {
269            }
270        }
271    }
272
273    /**
274     * Test for <code>getInstance(String algorithm, Provider provider)</code> method
275     * Assertion: returns Mac object
276     */
277    public void testMac08() throws NoSuchAlgorithmException, NoSuchProviderException,
278            IllegalArgumentException {
279        if (!DEFSupported) {
280            fail(NotSupportedMsg);
281            return;
282        }
283        Mac mac;
284        for (int i = 0; i < validValues.length; i++) {
285            mac = Mac.getInstance(validValues[i], defaultProvider);
286            assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
287            assertEquals("Incorrect provider", mac.getProvider(), defaultProvider);
288        }
289    }
290    /**
291     * Test for <code>update</code> and <code>doFinal</code> methods
292     * Assertion: throws IllegalStateException when Mac is not initialized
293     * @throws Exception
294     */
295    public void testMac09() throws Exception {
296        if (!DEFSupported) {
297            fail(NotSupportedMsg);
298            return;
299        }
300        Mac [] macs = createMacs();
301        assertNotNull("Mac objects were not created", macs);
302        byte [] buf = new byte[10];
303        ByteBuffer bBuf = ByteBuffer.wrap(buf, 0, 10);
304        byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
305        SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
306        for (int i = 0; i < macs.length; i++) {
307            try {
308                macs[i].update((byte)0);
309                fail("IllegalStateException must be thrown");
310            } catch (IllegalStateException e) {
311            }
312            try {
313                macs[i].update(buf);
314                fail("IllegalStateException must be thrown");
315            } catch (IllegalStateException e) {
316            }
317            try {
318                macs[i].update(buf, 0, 3);
319                fail("IllegalStateException must be thrown");
320            } catch (IllegalStateException e) {
321            }
322            try {
323                macs[i].update(bBuf);
324                fail("IllegalStateException must be thrown");
325            } catch (IllegalStateException e) {
326            }
327            try {
328                macs[i].doFinal();
329                fail("IllegalStateException must be thrown");
330            } catch (IllegalStateException e) {
331            }
332            try {
333                macs[i].doFinal(new byte[10]);
334                fail("IllegalStateException must be thrown");
335            } catch (IllegalStateException e) {
336            }
337            try {
338                macs[i].doFinal(new byte[10], 0);
339                fail("IllegalStateException must be thrown");
340            } catch (IllegalStateException e) {
341            }
342
343            macs[i].init(sks);
344            try {
345                macs[i].doFinal(new byte[1], 0);
346                fail("ShortBufferException expected");
347            } catch (ShortBufferException e) {
348                //expected
349            }
350        }
351    }
352    /**
353     * Test for <code>doFinal(byte[] output, int outOffset)</code> method
354     * Assertion:
355     * throws ShotBufferException when outOffset  is negative or
356     * outOffset >= output.length  or when given buffer is small
357     */
358    public void testMac10() throws Exception {
359        if (!DEFSupported) {
360            fail(NotSupportedMsg);
361            return;
362        }
363        Mac[] macs = createMacs();
364        assertNotNull("Mac objects were not created", macs);
365        byte[] b = { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
366        byte[] byteA = new byte[b.length];
367        SecretKeySpec sks = new SecretKeySpec(b, "SHA1");
368        for (int i = 0; i < macs.length; i++) {
369            macs[i].init(sks);
370            try {
371                macs[i].doFinal(null, 10);
372                fail("ShortBufferException must be thrown");
373            } catch (ShortBufferException e) {
374            }
375            try {
376                macs[i].doFinal(byteA, -4);
377                fail("ShortBufferException must be thrown");
378            } catch (ShortBufferException e) {
379            }
380            try {
381                macs[i].doFinal(byteA, 10);
382                fail("ShortBufferException must be thrown");
383            } catch (ShortBufferException e) {
384            }
385            try {
386                macs[i].doFinal(new byte[1], 0);
387                fail("ShortBufferException must be thrown");
388            } catch (ShortBufferException e) {
389            }
390            byte[] res = macs[i].doFinal();
391            try {
392                macs[i].doFinal(new byte[res.length - 1], 0);
393                fail("ShortBufferException must be thrown");
394            } catch (ShortBufferException e) {
395            }
396        }
397    }
398
399    /**
400     * Test for <code>doFinal(byte[] output, int outOffset)</code> and
401     * <code>doFinal()</code> methods Assertion: Mac result is stored in
402     * output buffer
403     */
404    public void testMac11() throws Exception {
405        if (!DEFSupported) {
406            fail(NotSupportedMsg);
407            return;
408        }
409        Mac [] macs = createMacs();
410        assertNotNull("Mac objects were not created", macs);
411        byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
412        SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
413        for (int i = 0; i < macs.length; i++) {
414            macs[i].init(scs);
415            byte [] res1 = macs[i].doFinal();
416            byte [] res2 = new byte[res1.length + 10];
417            macs[i].doFinal(res2, 0);
418            for (int j = 0; j < res1.length; j++) {
419                assertEquals("Not equals byte number: "
420                        .concat(Integer.toString(j)), res1[j], res2[j]);
421            }
422        }
423    }
424    /**
425     * Test for <code>doFinal(byte[] input)</code> method
426     * Assertion: update Mac and returns result
427     */
428    public void testMac12() throws Exception {
429        if (!DEFSupported) {
430            fail(NotSupportedMsg);
431            return;
432        }
433        Mac [] macs = createMacs();
434        assertNotNull("Mac objects were not created", macs);
435        byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
436        byte [] upd = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1, (byte)0};
437        SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
438        for (int i = 0; i < macs.length; i++) {
439            macs[i].init(scs);
440            byte[] res1 = macs[i].doFinal();
441            byte[] res2 = macs[i].doFinal();
442            assertEquals("Results are not the same",
443                    Arrays.toString(res1),
444                    Arrays.toString(res2));
445
446            res2 = macs[i].doFinal(upd);
447            macs[i].update(upd);
448            res1 = macs[i].doFinal();
449            assertEquals("Results are not the same",
450                    Arrays.toString(res1),
451                    Arrays.toString(res2));
452        }
453    }
454
455    /**
456     * Test for <code>update(byte[] input, int outset, int len)</code> method
457     * Assertion: throws IllegalArgumentException when offset or len is negative,
458     * offset + len >= input.length
459     */
460    public void testMac13() throws Exception {
461        if (!DEFSupported) {
462            fail(NotSupportedMsg);
463            return;
464        }
465        Mac [] macs = createMacs();
466        assertNotNull("Mac objects were not created", macs);
467        byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
468        SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
469        for (int i = 0; i < macs.length; i++) {
470            macs[i].init(scs);
471            try {
472                macs[i].update(b, -10, b.length);
473                fail("IllegalArgumentException must be thrown");
474            } catch (IllegalArgumentException e) {
475            }
476            try {
477                macs[i].update(b, 0, -10);
478                fail("IllegalArgumentException must be thrown");
479            } catch (IllegalArgumentException e) {
480            }
481            try {
482                macs[i].update(b, 0, b.length + 1);
483                fail("IllegalArgumentException must be thrown");
484            } catch (IllegalArgumentException e) {
485            }
486            try {
487                macs[i].update(b, b.length - 1, 2);
488                fail("IllegalArgumentException must be thrown");
489            } catch (IllegalArgumentException e) {
490            }
491        }
492    }
493    /**
494     * Test for <code>update(byte[] input, int outset, int len)</code> and
495     * <code>update(byte[] input</code>
496     * methods
497     * Assertion: updates Mac
498     */
499    public void testMac14() throws Exception {
500        if (!DEFSupported) {
501            fail(NotSupportedMsg);
502            return;
503        }
504        Mac [] macs = createMacs();
505        assertNotNull("Mac objects were not created", macs);
506        byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
507        byte [] upd1 = {(byte)0, (byte)1, (byte)5, (byte)4, (byte)3, (byte)2};
508        byte [] upd2 = {(byte)5, (byte)4, (byte)3, (byte)2};
509        byte [] res1;
510        byte [] res2;
511        SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
512        for (int i = 0; i < macs.length; i++) {
513            macs[i].init(scs);
514            macs[i].update(upd1, 2, 4);
515            res1 = macs[i].doFinal();
516            macs[i].init(scs);
517            macs[i].update(upd2);
518            res2 = macs[i].doFinal();
519            assertEquals("Results are not the same", res1.length, res2.length);
520            for(int t = 0; t < res1.length; t++) {
521                assertEquals("Results are not the same", res1[t], res2[t]);
522            }
523            macs[i].init(scs);
524            macs[i].update((byte)5);
525            res1 = macs[i].doFinal();
526            macs[i].init(scs);
527            macs[i].update(upd1,2,1);
528            res2 = macs[i].doFinal();
529            assertEquals("Results are not the same", res1.length, res2.length);
530            for(int t = 0; t < res1.length; t++) {
531                assertEquals("Results are not the same", res1[t], res2[t]);
532            }
533        }
534    }
535    /**
536     * Test for <code>clone()</code> method
537     * Assertion: returns Mac object or throws CloneNotSupportedException
538     */
539    public void testMacClone() throws Exception {
540        if (!DEFSupported) {
541            fail(NotSupportedMsg);
542            return;
543        }
544        Mac [] macs = createMacs();
545        assertNotNull("Mac objects were not created", macs);
546        for (int i = 0; i < macs.length; i++) {
547            try {
548                Mac mac1 = (Mac) macs[i].clone();
549                assertEquals(mac1.getAlgorithm(), macs[i].getAlgorithm());
550                assertEquals(mac1.getProvider(), macs[i].getProvider());
551                assertFalse(macs[i].equals(mac1));
552            } catch (CloneNotSupportedException e) {
553            }
554        }
555    }
556    /**
557     * Test for
558     * <code>init(Key key, AlgorithmParameterSpec params)</code>
559     * <code>init(Key key)</code>
560     * methods
561     * Assertion: throws InvalidKeyException and InvalidAlgorithmParameterException
562     * when parameters are not appropriate
563     */
564    public void testInit() throws Exception {
565        if (!DEFSupported) {
566            fail(NotSupportedMsg);
567            return;
568        }
569        Mac [] macs = createMacs();
570        assertNotNull("Mac objects were not created", macs);
571        byte [] b = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
572        SecretKeySpec sks = new SecretKeySpec(b, "SHA1");
573        DHGenParameterSpec algPS = new DHGenParameterSpec(1, 2);
574        PSSParameterSpec algPSS = new PSSParameterSpec(20);
575        SecretKeySpec sks1 = new SecretKeySpec(b, "RSA");
576
577        for (int i = 0; i < macs.length; i++) {
578            macs[i].reset();
579            macs[i].init(sks);
580            try {
581                macs[i].init(sks1, algPSS);
582                fail("init(..) accepts incorrect AlgorithmParameterSpec parameter");
583            } catch (InvalidAlgorithmParameterException e) {
584            }
585            try {
586                macs[i].init(sks, algPS);
587                fail("init(..) accepts incorrect AlgorithmParameterSpec parameter");
588            } catch (InvalidAlgorithmParameterException e) {
589            }
590
591            try {
592                macs[i].init(null, null);
593                fail("InvalidKeyException must be thrown");
594            } catch (InvalidKeyException e) {
595            }
596
597            try {
598                macs[i].init(null);
599                fail("InvalidKeyException must be thrown");
600            } catch (InvalidKeyException e) {
601            }
602//            macs[i].init(sks, null);
603        }
604    }
605
606    /**
607     * Test for <code>update(ByteBuffer input)</code>
608     * <code>update(byte[] input, int offset, int len)</code>
609     * methods
610     * Assertion: processes Mac; if input is null then do nothing
611     */
612    public void testUpdateByteBuffer01() throws Exception {
613        if (!DEFSupported) {
614            fail(NotSupportedMsg);
615            return;
616        }
617        Mac [] macs = createMacs();
618        assertNotNull("Mac objects were not created", macs);
619        byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
620        SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
621        ByteBuffer byteNull = null;
622        ByteBuffer byteBuff = ByteBuffer.allocate(0);
623        byte [] bb1;
624        byte [] bb2;
625        for (int i = 0; i < macs.length; i++) {
626            macs[i].init(sks);
627            bb1 = macs[i].doFinal();
628            try {
629                macs[i].update(byteNull);
630                fail("IllegalArgumentException must be thrown because buffer is null");
631            } catch (IllegalArgumentException e) {
632            }
633            macs[i].update(byteBuff);
634            bb2 = macs[i].doFinal();
635            for (int t = 0; t < bb1.length; t++) {
636                assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
637            }
638            macs[i].init(sks);
639            bb1 = macs[i].doFinal();
640            macs[i].update(null, 0, 0);
641            bb2 = macs[i].doFinal();
642            for (int t = 0; t < bb1.length; t++) {
643                assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
644            }
645        }
646    }
647    /**
648     * Test for <code>update(ByteBuffer input)</code>
649     * <code>update(byte[] input, int offset, int len)</code>
650     * methods
651     * Assertion: processes Mac
652     */
653    public void testUpdateByteBuffer02() throws Exception {
654        if (!DEFSupported) {
655            fail(NotSupportedMsg);
656            return;
657        }
658        Mac [] macs = createMacs();
659        assertNotNull("Mac objects were not created", macs);
660        byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
661        SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
662        byte [] bbuf = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1};
663        ByteBuffer byteBuf;
664        byte [] bb1;
665        byte [] bb2;
666        for (int i = 0; i < macs.length; i++) {
667            byteBuf = ByteBuffer.allocate(5);
668            byteBuf.put(bbuf);
669            byteBuf.position(2);
670            macs[i].init(sks);
671            macs[i].update(byteBuf);
672            bb1 = macs[i].doFinal();
673
674            macs[i].init(sks);
675            macs[i].update(bbuf, 2, 3);
676            bb2 = macs[i].doFinal();
677            for (int t = 0; t < bb1.length; t++) {
678                assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
679            }
680        }
681    }
682    /**
683     * Test for <code>clone()</code> method
684     * Assertion: clone if provider is clo
685     */
686    public void testClone() throws Exception {
687        if (!DEFSupported) {
688            fail(NotSupportedMsg);
689            return;
690        }
691        Mac [] macs = createMacs();
692        assertNotNull("Mac objects were not created", macs);
693        Mac res;
694        for (int i = 0; i < macs.length; i++) {
695            try {
696                res = (Mac)macs[i].clone();
697                assertTrue("Object should not be equals", !macs[i].equals(res));
698                assertEquals("Incorrect class", macs[i].getClass(), res.getClass());
699            } catch (CloneNotSupportedException e) {
700            }
701        }
702    }
703    /**
704     * Test for <code>getMacLength()</code> method
705     * Assertion: return Mac length
706     */
707    public void testGetMacLength() throws Exception {
708        if (!DEFSupported) {
709            fail(NotSupportedMsg);
710            return;
711        }
712        Mac [] macs = createMacs();
713        assertNotNull("Mac objects were not created", macs);
714        for (int i = 0; i < macs.length; i++) {
715            assertTrue("Length should be positive", (macs[i].getMacLength() >= 0));
716        }
717    }
718
719    /**
720     * Test for <code>reset()</code> method
721     * Assertion: return Mac length
722     */
723    public void testReset() throws Exception {
724        if (!DEFSupported) {
725            fail(NotSupportedMsg);
726            return;
727        }
728        Mac [] macs = createMacs();
729        assertNotNull("Mac objects were not created", macs);
730        byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
731        SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
732        byte [] bbuf = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1};
733        byte [] bb1;
734        byte [] bb2;
735        for (int i = 0; i < macs.length; i++) {
736            macs[i].init(sks);
737            bb1 = macs[i].doFinal();
738            macs[i].reset();
739            bb2 = macs[i].doFinal();
740            assertEquals("incorrect result",bb1.length, bb2.length);
741            for (int t = 0; t < bb1.length; t++) {
742               assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
743            }
744            macs[i].reset();
745            macs[i].update(bbuf);
746            bb1 = macs[i].doFinal();
747            macs[i].reset();
748            macs[i].update(bbuf, 0, bbuf.length);
749            bb2 = macs[i].doFinal();
750            assertEquals("incorrect result",bb1.length, bb2.length);
751            for (int t = 0; t < bb1.length; t++) {
752               assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
753            }
754        }
755    }
756    /**
757     * Test for <code>Mac</code> constructor
758     * Assertion: returns Mac object
759     */
760    public void testMacConstructor() throws NoSuchAlgorithmException,
761            InvalidKeyException, InvalidAlgorithmParameterException {
762        if (!DEFSupported) {
763            fail(NotSupportedMsg);
764            return;
765        }
766        MacSpi spi = new MyMacSpi();
767        Mac mac = new myMac(spi, defaultProvider, defaultAlgorithm);
768        assertEquals("Incorrect algorithm", defaultAlgorithm, mac.getAlgorithm());
769        assertEquals("Incorrect provider", defaultProvider, mac.getProvider());
770        try {
771            mac.init(null, null);
772            fail("Exception should be thrown because init(..) uses incorrect parameters");
773        } catch (Exception e) {
774        }
775        assertEquals("Invalid mac length", 0, mac.getMacLength());
776
777        mac = new myMac(null, null, null);
778        assertNull("Algorithm must be null", mac.getAlgorithm());
779        assertNull("Provider must be null", mac.getProvider());
780        try {
781            mac.init(null, null);
782            fail("Exception should be thrown because init(..) uses incorrect parameters");
783        } catch (Exception e) {
784        }
785        try {
786            mac.getMacLength();
787            fail("NullPointerException must be thrown");
788        } catch (NullPointerException e) {
789        }
790    }
791
792    public void test_getAlgorithm() throws NoSuchAlgorithmException {
793        Mac mac;
794        for (int i = 0; i < validValues.length; i++) {
795            mac = Mac.getInstance(validValues[i]);
796            assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
797        }
798
799        mac = new Mock_Mac(null, null, null);
800        assertNull(mac.getAlgorithm());
801    }
802
803    public void test_getProvider() throws NoSuchAlgorithmException {
804        Mac mac;
805        for (int i = 0; i < validValues.length; i++) {
806            mac = Mac.getInstance(validValues[i]);
807            assertNotNull(mac.getProvider());
808        }
809
810        mac = new Mock_Mac(null, null, null);
811        assertNull(mac.getProvider());
812    }
813
814    private static final byte[] TEST_INPUT = new byte[] {
815            0x01, (byte) 0xFF, 0x55, (byte) 0xAA
816    };
817
818    public void test_ConsistentBetweenProviders() throws Exception {
819        SecretKey key = new SecretKeySpec(new byte[] {
820                (byte) 0x7b, (byte) 0x10, (byte) 0x6d, (byte) 0x68, (byte) 0x3f, (byte) 0x70,
821                (byte) 0xa3, (byte) 0xb5, (byte) 0xa3, (byte) 0xdd, (byte) 0x9f, (byte) 0x54,
822                (byte) 0x74, (byte) 0x36, (byte) 0xde, (byte) 0xa7, (byte) 0x88, (byte) 0x81,
823                (byte) 0x0d, (byte) 0x89, (byte) 0xef, (byte) 0x2e, (byte) 0x42, (byte) 0x4f,
824        }, "HmacMD5");
825        byte[] label = new byte[] {
826                (byte) 0x6b, (byte) 0x65, (byte) 0x79, (byte) 0x20, (byte) 0x65, (byte) 0x78,
827                (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x73, (byte) 0x69, (byte) 0x6f,
828                (byte) 0x6e,
829        };
830        byte[] seed = new byte[] {
831                (byte) 0x50, (byte) 0xf9, (byte) 0xce, (byte) 0x14, (byte) 0xb2, (byte) 0xdd,
832                (byte) 0x3d, (byte) 0xfa, (byte) 0x96, (byte) 0xd9, (byte) 0xfe, (byte) 0x3a,
833                (byte) 0x1a, (byte) 0xe5, (byte) 0x79, (byte) 0x55, (byte) 0xe7, (byte) 0xbc,
834                (byte) 0x84, (byte) 0x68, (byte) 0x0e, (byte) 0x2d, (byte) 0x20, (byte) 0xd0,
835                (byte) 0x6e, (byte) 0xb4, (byte) 0x03, (byte) 0xbf, (byte) 0xa2, (byte) 0xe6,
836                (byte) 0xc4, (byte) 0x9d, (byte) 0x50, (byte) 0xf9, (byte) 0xce, (byte) 0x14,
837                (byte) 0xbc, (byte) 0xc5, (byte) 0x9e, (byte) 0x9a, (byte) 0x36, (byte) 0xa7,
838                (byte) 0xaa, (byte) 0xfe, (byte) 0x3b, (byte) 0xca, (byte) 0xcb, (byte) 0x4c,
839                (byte) 0xfa, (byte) 0x87, (byte) 0x9a, (byte) 0xac, (byte) 0x02, (byte) 0x25,
840                (byte) 0xce, (byte) 0xda, (byte) 0x74, (byte) 0x10, (byte) 0x86, (byte) 0x9c,
841                (byte) 0x03, (byte) 0x18, (byte) 0x0f, (byte) 0xe2,
842        };
843        Provider[] providers = Security.getProviders("Mac.HmacMD5");
844        Provider defProvider = null;
845        byte[] output = null;
846        byte[] output2 = null;
847        for (int i = 0; i < providers.length; i++) {
848            System.out.println("provider = " + providers[i].getName());
849            Mac mac = Mac.getInstance("HmacMD5", providers[i]);
850            mac.init(key);
851            mac.update(label);
852            mac.update(seed);
853            if (output == null) {
854                output = new byte[mac.getMacLength()];
855                defProvider = providers[i];
856                mac.doFinal(output, 0);
857                mac.init(new SecretKeySpec(label, "HmacMD5"));
858                output2 = mac.doFinal(output);
859            } else {
860                byte[] tmp = new byte[mac.getMacLength()];
861                mac.doFinal(tmp, 0);
862                assertEquals(defProvider.getName() + " vs. " + providers[i].getName(),
863                        Arrays.toString(output), Arrays.toString(tmp));
864                mac.init(new SecretKeySpec(label, "HmacMD5"));
865                assertEquals(defProvider.getName() + " vs. " + providers[i].getName(),
866                        Arrays.toString(output2), Arrays.toString(mac.doFinal(output)));
867            }
868
869        }
870    }
871
872    class Mock_Mac extends Mac {
873        protected Mock_Mac(MacSpi arg0, Provider arg1, String arg2) {
874            super(arg0, arg1, arg2);
875        }
876    }
877
878    private static abstract class MockProvider extends Provider {
879        public MockProvider(String name) {
880            super(name, 1.0, "Mock provider used for testing");
881            setup();
882        }
883
884        public abstract void setup();
885    }
886
887    public void testMac_getInstance_SuppliedProviderNotRegistered_Success() throws Exception {
888        Provider mockProvider = new MockProvider("MockProvider") {
889            public void setup() {
890                put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
891            }
892        };
893
894        {
895            Mac s = Mac.getInstance("FOO", mockProvider);
896            s.init(new MockKey());
897            assertEquals(mockProvider, s.getProvider());
898        }
899    }
900
901    public void testMac_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
902            throws Exception {
903        Provider mockProvider = new MockProvider("MockProvider") {
904            public void setup() {
905                put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
906            }
907        };
908
909        Security.addProvider(mockProvider);
910        try {
911            {
912                Provider mockProvider2 = new MockProvider("MockProvider") {
913                    public void setup() {
914                        put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
915                    }
916                };
917                Mac s = Mac.getInstance("FOO", mockProvider2);
918                assertEquals(mockProvider2, s.getProvider());
919            }
920        } finally {
921            Security.removeProvider(mockProvider.getName());
922        }
923    }
924
925    public void testMac_getInstance_DelayedInitialization_KeyType() throws Exception {
926        Provider mockProviderSpecific = new MockProvider("MockProviderSpecific") {
927            public void setup() {
928                put("Mac.FOO", MockMacSpi.SpecificKeyTypes.class.getName());
929                put("Mac.FOO SupportedKeyClasses", MockKey.class.getName());
930            }
931        };
932        Provider mockProviderSpecific2 = new MockProvider("MockProviderSpecific2") {
933            public void setup() {
934                put("Mac.FOO", MockMacSpi.SpecificKeyTypes2.class.getName());
935                put("Mac.FOO SupportedKeyClasses", MockKey2.class.getName());
936            }
937        };
938        Provider mockProviderAll = new MockProvider("MockProviderAll") {
939            public void setup() {
940                put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
941            }
942        };
943
944        Security.addProvider(mockProviderSpecific);
945        Security.addProvider(mockProviderSpecific2);
946        Security.addProvider(mockProviderAll);
947
948        try {
949            {
950                Mac s = Mac.getInstance("FOO");
951                s.init(new MockKey());
952                assertEquals(mockProviderSpecific, s.getProvider());
953
954                try {
955                    s.init(new MockKey2());
956                    assertEquals(mockProviderSpecific2, s.getProvider());
957                    if (StandardNames.IS_RI) {
958                        fail("RI was broken before; fix tests now that it works!");
959                    }
960                } catch (InvalidKeyException e) {
961                    if (!StandardNames.IS_RI) {
962                        fail("Non-RI should select the right provider");
963                    }
964                }
965            }
966
967            {
968                Mac s = Mac.getInstance("FOO");
969                s.init(new PrivateKey() {
970                    @Override
971                    public String getAlgorithm() {
972                        throw new UnsupportedOperationException("not implemented");
973                    }
974
975                    @Override
976                    public String getFormat() {
977                        throw new UnsupportedOperationException("not implemented");
978                    }
979
980                    @Override
981                    public byte[] getEncoded() {
982                        throw new UnsupportedOperationException("not implemented");
983                    }
984                });
985                assertEquals(mockProviderAll, s.getProvider());
986            }
987
988            {
989                Mac s = Mac.getInstance("FOO");
990                assertEquals(mockProviderSpecific, s.getProvider());
991            }
992        } finally {
993            Security.removeProvider(mockProviderSpecific.getName());
994            Security.removeProvider(mockProviderSpecific2.getName());
995            Security.removeProvider(mockProviderAll.getName());
996        }
997    }
998
999    public static Test suite() {
1000        return new TestSuite(MacTest.class);
1001    }
1002}
1003/**
1004 * Additional class for Mac constructor verification
1005 */
1006class myMac extends Mac {
1007
1008    public myMac(MacSpi macSpi, Provider provider,
1009            String algorithm) {
1010        super(macSpi, provider, algorithm);
1011    }
1012}
1013