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 dalvik.annotation.TestTargetClass;
26import dalvik.annotation.TestTargets;
27import dalvik.annotation.TestLevel;
28import dalvik.annotation.TestTargetNew;
29
30import java.math.BigInteger;
31import java.nio.ByteBuffer;
32import java.security.InvalidAlgorithmParameterException;
33import java.security.InvalidKeyException;
34import java.security.NoSuchAlgorithmException;
35import java.security.NoSuchProviderException;
36import java.security.Provider;
37import java.security.spec.DSAParameterSpec;
38import java.security.spec.PSSParameterSpec;
39
40import javax.crypto.Mac;
41import javax.crypto.MacSpi;
42import javax.crypto.ShortBufferException;
43import javax.crypto.spec.DHGenParameterSpec;
44
45import javax.crypto.spec.SecretKeySpec;
46
47import org.apache.harmony.crypto.tests.support.MyMacSpi;
48import org.apache.harmony.security.tests.support.SpiEngUtils;
49
50import junit.framework.TestCase;
51
52import junit.framework.Test;
53import junit.framework.TestSuite;
54
55@TestTargetClass(Mac.class)
56/**
57 * Tests for Mac class constructors and methods
58 *
59 */
60
61public class MacTest extends TestCase {
62
63    public static final String srvMac = "Mac";
64
65    private static String defaultAlgorithm = null;
66
67    private static String defaultProviderName = null;
68
69    private static Provider defaultProvider = null;
70
71    private static boolean DEFSupported = false;
72
73    private static final String NotSupportedMsg = "There is no suitable provider for Mac";
74
75    private static final String[] invalidValues = SpiEngUtils.invalidValues;
76
77    private static String[] validValues = new String[3];
78
79    public static final String validAlgorithmsMac [] =
80        {"HmacSHA1", "HmacMD5", "HmacSHA256", "HmacSHA384", "HmacSHA512"};
81
82
83    static {
84        for (int i = 0; i < validAlgorithmsMac.length; i++) {
85            defaultProvider = SpiEngUtils.isSupport(validAlgorithmsMac[i],
86                    srvMac);
87            DEFSupported = (defaultProvider != null);
88            if (DEFSupported) {
89                defaultAlgorithm = validAlgorithmsMac[i];
90                defaultProviderName = defaultProvider.getName();
91                validValues[0] = defaultAlgorithm;
92                validValues[1] = defaultAlgorithm.toUpperCase();
93                validValues[2] = defaultAlgorithm.toLowerCase();
94                break;
95            }
96        }
97    }
98
99    private Mac [] createMacs() {
100        if (!DEFSupported) {
101            fail(NotSupportedMsg);
102            return null;
103        }
104        try {
105            Mac m [] = new Mac[3];
106            m[0] = Mac.getInstance(defaultAlgorithm);
107            m[1] = Mac.getInstance(defaultAlgorithm, defaultProvider);
108            m[2] = Mac.getInstance(defaultAlgorithm, defaultProviderName);
109            return m;
110        } catch (Exception e) {
111            return null;
112        }
113    }
114
115    /**
116     * Test for <code>getInstance(String algorithm)</code> method
117     * Assertion:
118     * throws NullPointerException when algorithm is null
119     * throws NoSuchAlgorithmException when algorithm is not available
120     */
121    @TestTargetNew(
122        level = TestLevel.PARTIAL_COMPLETE,
123        notes = "This is a complete subset of tests for getInstance method.",
124        method = "getInstance",
125        args = {java.lang.String.class}
126    )
127    public void testMac01() {
128        try {
129            Mac.getInstance(null);
130            fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
131        } catch (NullPointerException e) {
132        } catch (NoSuchAlgorithmException e) {
133        }
134        for (int i = 0; i < invalidValues.length; i++) {
135            try {
136                Mac.getInstance(invalidValues[i]);
137                fail("NoSuchAlgorithmException must be thrown when algorithm is not available: "
138                        .concat(invalidValues[i]));
139            } catch (NoSuchAlgorithmException e) {
140            }
141        }
142    }
143
144    /**
145     * Test for <code>getInstance(String algorithm)</code> method
146     * Assertion: returns Mac object
147     */
148    @TestTargetNew(
149        level = TestLevel.PARTIAL_COMPLETE,
150        notes = "This is a complete subset of tests for getInstance method.",
151        method = "getInstance",
152        args = {java.lang.String.class}
153    )
154    public void testMac02() throws NoSuchAlgorithmException {
155        if (!DEFSupported) {
156            fail(NotSupportedMsg);
157            return;
158        }
159        Mac mac;
160        for (int i = 0; i < validValues.length; i++) {
161            mac = Mac.getInstance(validValues[i]);
162            assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
163        }
164    }
165    /**
166     * Test for <code>getInstance(String algorithm, String provider)</code> method
167     * Assertion:
168     * throws IllegalArgumentException when provider is null or empty
169     * throws NoSuchProviderException when provider is not available
170     */
171    @TestTargetNew(
172        level = TestLevel.PARTIAL_COMPLETE,
173        notes = "This is a complete subset of tests for getInstance method.",
174        method = "getInstance",
175        args = {java.lang.String.class, java.lang.String.class}
176    )
177    public void testMac03() throws NoSuchAlgorithmException, NoSuchProviderException {
178        if (!DEFSupported) {
179            fail(NotSupportedMsg);
180            return;
181        }
182        String provider = null;
183        for (int i = 0; i < validValues.length; i++) {
184            try {
185                Mac.getInstance(validValues[i], provider);
186                fail("IllegalArgumentException must be thrown when provider is null");
187            } catch (IllegalArgumentException e) {
188            }
189            try {
190                Mac.getInstance(validValues[i], "");
191                fail("IllegalArgumentException must be thrown when provider is empty");
192            } catch (IllegalArgumentException e) {
193            }
194            for (int j = 1; j < invalidValues.length; j++) {
195                try {
196                    Mac.getInstance(validValues[i], invalidValues[j]);
197                    fail("NoSuchProviderException must be thrown (algorithm: "
198                            .concat(validValues[i]).concat(" provider: ")
199                            .concat(invalidValues[j]).concat(")"));
200                } catch (NoSuchProviderException e) {
201                }
202            }
203        }
204    }
205
206    /**
207     * Test for <code>getInstance(String algorithm, String provider)</code> method
208     * Assertion:
209     * throws NullPointerException when algorithm is null
210     * throws NoSuchAlgorithmException when algorithm is not available
211     */
212    @TestTargetNew(
213        level = TestLevel.PARTIAL_COMPLETE,
214        notes = "This is a complete subset of tests for getInstance method.",
215        method = "getInstance",
216        args = {java.lang.String.class, java.lang.String.class}
217    )
218    public void testMac04() throws NoSuchAlgorithmException,
219            IllegalArgumentException, NoSuchProviderException {
220        if (!DEFSupported) {
221            fail(NotSupportedMsg);
222            return;
223        }
224        try {
225            Mac.getInstance(null, defaultProviderName);
226            fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
227        } catch (NullPointerException e) {
228        } catch (NoSuchAlgorithmException e) {
229        }
230        for (int i = 0; i < invalidValues.length; i++) {
231            try {
232                Mac.getInstance(invalidValues[i], defaultProviderName);
233                fail("NoSuchAlgorithmException must be throws when algorithm is not available: "
234                        .concat(invalidValues[i]));
235            } catch( NoSuchAlgorithmException e) {
236            }
237        }
238    }
239    /**
240     * Test for <code>getInstance(String algorithm, String provider)</code> method
241     * Assertion: returns Mac object
242     */
243    @TestTargetNew(
244        level = TestLevel.PARTIAL_COMPLETE,
245        notes = "This is a complete subset of tests for getInstance method.",
246        method = "getInstance",
247        args = {java.lang.String.class, java.lang.String.class}
248    )
249    public void testMac05() throws NoSuchAlgorithmException, NoSuchProviderException,
250            IllegalArgumentException {
251        if (!DEFSupported) {
252            fail(NotSupportedMsg);
253            return;
254        }
255        Mac mac;
256        for (int i = 0; i < validValues.length; i++) {
257            mac = Mac.getInstance(validValues[i], defaultProviderName);
258            assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
259            assertEquals("Incorrect provider", mac.getProvider().getName(),
260                    defaultProviderName);
261        }
262    }
263
264    /**
265     * Test for <code>getInstance(String algorithm, Provider provider)</code> method
266     * Assertion: throws IllegalArgumentException when provider is null
267     */
268    @TestTargetNew(
269        level = TestLevel.PARTIAL_COMPLETE,
270        notes = "This is a complete subset of tests for getInstance method.",
271        method = "getInstance",
272        args = {java.lang.String.class, java.security.Provider.class}
273    )
274    public void testMac06() throws NoSuchAlgorithmException, NoSuchProviderException {
275        if (!DEFSupported) {
276            fail(NotSupportedMsg);
277            return;
278        }
279        Provider provider = null;
280        for (int i = 0; i < validValues.length; i++) {
281            try {
282                Mac.getInstance(validValues[i], provider);
283                fail("IllegalArgumentException must be thrown when provider is null");
284            } catch (IllegalArgumentException e) {
285            }
286        }
287    }
288    /**
289     * Test for <code>getInstance(String algorithm, Provider provider)</code> method
290     * Assertion:
291     * throws NullPointerException when algorithm is null
292     * throws NoSuchAlgorithmException when algorithm is not available
293     */
294    @TestTargetNew(
295        level = TestLevel.PARTIAL_COMPLETE,
296        notes = "This is a complete subset of tests for getInstance method.",
297        method = "getInstance",
298        args = {java.lang.String.class, java.security.Provider.class}
299    )
300    public void testMac07() throws NoSuchAlgorithmException,
301            NoSuchProviderException, IllegalArgumentException {
302        if (!DEFSupported) {
303            fail(NotSupportedMsg);
304            return;
305        }
306        try {
307            Mac.getInstance(null, defaultProvider);
308            fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
309        } catch (NullPointerException e) {
310        } catch (NoSuchAlgorithmException e) {
311        }
312        for (int i = 0; i < invalidValues.length; i++) {
313            try {
314                Mac.getInstance(invalidValues[i], defaultProvider);
315                fail("NoSuchAlgorithmException must be thrown when algorithm is not available: "
316                        .concat(invalidValues[i]));
317            } catch (NoSuchAlgorithmException e) {
318            }
319        }
320    }
321
322    /**
323     * Test for <code>getInstance(String algorithm, Provider provider)</code> method
324     * Assertion: returns Mac object
325     */
326    @TestTargetNew(
327        level = TestLevel.PARTIAL_COMPLETE,
328        notes = "This is a complete subset of tests for getInstance method.",
329        method = "getInstance",
330        args = {java.lang.String.class, java.security.Provider.class}
331    )
332    public void testMac08() throws NoSuchAlgorithmException, NoSuchProviderException,
333            IllegalArgumentException {
334        if (!DEFSupported) {
335            fail(NotSupportedMsg);
336            return;
337        }
338        Mac mac;
339        for (int i = 0; i < validValues.length; i++) {
340            mac = Mac.getInstance(validValues[i], defaultProvider);
341            assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
342            assertEquals("Incorrect provider", mac.getProvider(), defaultProvider);
343        }
344    }
345    /**
346     * Test for <code>update</code> and <code>doFinal</code> methods
347     * Assertion: throws IllegalStateException when Mac is not initialized
348     * @throws Exception
349     */
350    @TestTargets({
351        @TestTargetNew(
352            level = TestLevel.COMPLETE,
353            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
354            method = "doFinal",
355            args = {}
356        ),
357        @TestTargetNew(
358            level = TestLevel.COMPLETE,
359            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
360            clazz = MacSpi.class,
361            method = "engineDoFinal",
362            args = {}
363        ),
364        @TestTargetNew(
365            level = TestLevel.COMPLETE,
366            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
367            method = "doFinal",
368            args = {byte[].class}
369        ),
370        @TestTargetNew(
371            level = TestLevel.PARTIAL_COMPLETE,
372            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
373            method = "doFinal",
374            args = {byte[].class, int.class}
375        ),
376        @TestTargetNew(
377            level = TestLevel.COMPLETE,
378            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
379            method = "update",
380            args = {byte.class}
381        ),
382        @TestTargetNew(
383            level = TestLevel.COMPLETE,
384            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
385            clazz = MacSpi.class,
386            method = "engineUpdate",
387            args = {byte.class}
388        ),
389        @TestTargetNew(
390            level = TestLevel.COMPLETE,
391            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
392            method = "update",
393            args = {byte[].class}
394        ),
395        @TestTargetNew(
396            level = TestLevel.COMPLETE,
397            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
398            method = "update",
399            args = {byte[].class, int.class, int.class}
400        ),
401        @TestTargetNew(
402            level = TestLevel.COMPLETE,
403            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
404            clazz = MacSpi.class,
405            method = "engineUpdate",
406            args = {byte[].class, int.class, int.class}
407        ),
408        @TestTargetNew(
409            level = TestLevel.COMPLETE,
410            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
411            method = "update",
412            args = {java.nio.ByteBuffer.class}
413        )
414    })
415    public void testMac09() throws Exception {
416        if (!DEFSupported) {
417            fail(NotSupportedMsg);
418            return;
419        }
420        Mac [] macs = createMacs();
421        assertNotNull("Mac objects were not created", macs);
422        byte [] buf = new byte[10];
423        ByteBuffer bBuf = ByteBuffer.wrap(buf, 0, 10);
424        byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
425        SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
426        for (int i = 0; i < macs.length; i++) {
427            try {
428                macs[i].update((byte)0);
429                fail("IllegalStateException must be thrown");
430            } catch (IllegalStateException e) {
431            }
432            try {
433                macs[i].update(buf);
434                fail("IllegalStateException must be thrown");
435            } catch (IllegalStateException e) {
436            }
437            try {
438                macs[i].update(buf, 0, 3);
439                fail("IllegalStateException must be thrown");
440            } catch (IllegalStateException e) {
441            }
442            try {
443                macs[i].update(bBuf);
444                fail("IllegalStateException must be thrown");
445            } catch (IllegalStateException e) {
446            }
447            try {
448                macs[i].doFinal();
449                fail("IllegalStateException must be thrown");
450            } catch (IllegalStateException e) {
451            }
452            try {
453                macs[i].doFinal(new byte[10]);
454                fail("IllegalStateException must be thrown");
455            } catch (IllegalStateException e) {
456            }
457            try {
458                macs[i].doFinal(new byte[10], 0);
459                fail("IllegalStateException must be thrown");
460            } catch (IllegalStateException e) {
461            }
462
463            macs[i].init(sks);
464            try {
465                macs[i].doFinal(new byte[1], 0);
466                fail("ShortBufferException expected");
467            } catch (ShortBufferException e) {
468                //expected
469            }
470        }
471    }
472    /**
473     * Test for <code>doFinal(byte[] output, int outOffset)</code> method
474     * Assertion:
475     * throws ShotBufferException when outOffset  is negative or
476     * outOffset >= output.length  or when given buffer is small
477     */
478    @TestTargetNew(
479        level = TestLevel.PARTIAL_COMPLETE,
480        notes = "Checks ShortBufferException",
481        method = "doFinal",
482        args = {byte[].class, int.class}
483    )
484    public void testMac10() throws NoSuchAlgorithmException,
485            NoSuchProviderException, IllegalArgumentException,
486            IllegalStateException, InvalidKeyException {
487        if (!DEFSupported) {
488            fail(NotSupportedMsg);
489            return;
490        }
491        Mac[] macs = createMacs();
492        assertNotNull("Mac objects were not created", macs);
493        byte[] b = { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
494        byte[] byteA = new byte[b.length];
495        SecretKeySpec sks = new SecretKeySpec(b, "SHA1");
496        for (int i = 0; i < macs.length; i++) {
497            macs[i].init(sks);
498            try {
499                macs[i].doFinal(null, 10);
500                fail("ShortBufferException must be thrown");
501            } catch (ShortBufferException e) {
502            }
503            try {
504                macs[i].doFinal(byteA, -4);
505                fail("ShortBufferException must be thrown");
506            } catch (ShortBufferException e) {
507            }
508            try {
509                macs[i].doFinal(byteA, 10);
510                fail("ShortBufferException must be thrown");
511            } catch (ShortBufferException e) {
512            }
513            try {
514                macs[i].doFinal(new byte[1], 0);
515                fail("ShortBufferException must be thrown");
516            } catch (ShortBufferException e) {
517            }
518            byte[] res = macs[i].doFinal();
519            try {
520                macs[i].doFinal(new byte[res.length - 1], 0);
521                fail("ShortBufferException must be thrown");
522            } catch (ShortBufferException e) {
523            }
524        }
525    }
526
527    /**
528     * Test for <code>doFinal(byte[] output, int outOffset)</code> and
529     * <code>doFinal()</code> methods Assertion: Mac result is stored in
530     * output buffer
531     */
532    @TestTargets({
533        @TestTargetNew(
534            level = TestLevel.PARTIAL_COMPLETE,
535            notes = "Checks functionality.",
536            method = "doFinal",
537            args = {}
538        ),
539        @TestTargetNew(
540            level = TestLevel.PARTIAL_COMPLETE,
541            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
542            clazz = MacSpi.class,
543            method = "engineDoFinal",
544            args = {}
545        ),
546        @TestTargetNew(
547            level = TestLevel.PARTIAL_COMPLETE,
548            notes = "Checks functionality.",
549            method = "doFinal",
550            args = {byte[].class, int.class}
551        )
552    })
553    public void testMac11() throws NoSuchAlgorithmException, NoSuchProviderException,
554            IllegalArgumentException, IllegalStateException,
555            InvalidKeyException, ShortBufferException {
556        if (!DEFSupported) {
557            fail(NotSupportedMsg);
558            return;
559        }
560        Mac [] macs = createMacs();
561        assertNotNull("Mac objects were not created", macs);
562        byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
563        SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
564        for (int i = 0; i < macs.length; i++) {
565            macs[i].init(scs);
566            byte [] res1 = macs[i].doFinal();
567            byte [] res2 = new byte[res1.length + 10];
568            macs[i].doFinal(res2, 0);
569            for (int j = 0; j < res1.length; j++) {
570                assertEquals("Not equals byte number: "
571                        .concat(Integer.toString(j)), res1[j], res2[j]);
572            }
573        }
574    }
575    /**
576     * Test for <code>doFinal(byte[] input)</code> method
577     * Assertion: update Mac and returns result
578     */
579    @TestTargets({
580        @TestTargetNew(
581            level = TestLevel.PARTIAL_COMPLETE,
582            notes = "Checks functionality.",
583            method = "doFinal",
584            args = {}
585        ),
586        @TestTargetNew(
587            level = TestLevel.PARTIAL_COMPLETE,
588            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
589            clazz = MacSpi.class,
590            method = "engineDoFinal",
591            args = {}
592        ),
593        @TestTargetNew(
594            level = TestLevel.PARTIAL_COMPLETE,
595            notes = "Checks functionality.",
596            method = "doFinal",
597            args = {byte[].class}
598        )
599    })
600    public void testMac12() throws NoSuchAlgorithmException, NoSuchProviderException,
601            IllegalArgumentException, IllegalStateException,
602            InvalidKeyException  {
603        if (!DEFSupported) {
604            fail(NotSupportedMsg);
605            return;
606        }
607        Mac [] macs = createMacs();
608        assertNotNull("Mac objects were not created", macs);
609        byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
610        byte [] upd = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1, (byte)0};
611        SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
612        for (int i = 0; i < macs.length; i++) {
613            macs[i].init(scs);
614            byte [] res1 = macs[i].doFinal();
615            byte [] res2 = macs[i].doFinal();
616            assertEquals("Results are not the same", res1.length, res2.length);
617            for(int t = 0; t < res1.length; t++) {
618                assertEquals("Results are not the same", res1[t], res2[t]);
619            }
620            res2 = macs[i].doFinal(upd);
621            macs[i].update(upd);
622            res1 = macs[i].doFinal();
623            assertEquals("Results are not the same", res1.length, res2.length);
624            for(int t = 0; t < res1.length; t++) {
625                assertEquals("Results are not the same", res1[t], res2[t]);
626            }
627        }
628    }
629
630    /**
631     * Test for <code>update(byte[] input, int outset, int len)</code> method
632     * Assertion: throws IllegalArgumentException when offset or len is negative,
633     * offset + len >= input.length
634     */
635    @TestTargets({
636        @TestTargetNew(
637            level = TestLevel.PARTIAL_COMPLETE,
638            notes = "Checks IllegalArgumentException",
639            method = "update",
640            args = {byte[].class, int.class, int.class}
641        ),
642        @TestTargetNew(
643            level = TestLevel.PARTIAL_COMPLETE,
644            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
645            clazz = MacSpi.class,
646            method = "engineUpdate",
647            args = {byte[].class, int.class, int.class}
648        )
649    })
650    public void testMac13() throws NoSuchAlgorithmException,
651            NoSuchProviderException, IllegalArgumentException, IllegalStateException,
652            InvalidKeyException {
653        if (!DEFSupported) {
654            fail(NotSupportedMsg);
655            return;
656        }
657        Mac [] macs = createMacs();
658        assertNotNull("Mac objects were not created", macs);
659        byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
660        SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
661        for (int i = 0; i < macs.length; i++) {
662            macs[i].init(scs);
663            try {
664                macs[i].update(b, -10, b.length);
665                fail("IllegalArgumentException must be thrown");
666            } catch (IllegalArgumentException e) {
667            }
668            try {
669                macs[i].update(b, 0, -10);
670                fail("IllegalArgumentException must be thrown");
671            } catch (IllegalArgumentException e) {
672            }
673            try {
674                macs[i].update(b, 0, b.length + 1);
675                fail("IllegalArgumentException must be thrown");
676            } catch (IllegalArgumentException e) {
677            }
678            try {
679                macs[i].update(b, b.length - 1, 2);
680                fail("IllegalArgumentException must be thrown");
681            } catch (IllegalArgumentException e) {
682            }
683        }
684    }
685    /**
686     * Test for <code>update(byte[] input, int outset, int len)</code> and
687     * <code>update(byte[] input</code>
688     * methods
689     * Assertion: updates Mac
690     */
691    @TestTargets({
692        @TestTargetNew(
693            level = TestLevel.PARTIAL_COMPLETE,
694            notes = "Checks functionality.",
695            method = "update",
696            args = {byte.class}
697        ),
698        @TestTargetNew(
699            level = TestLevel.PARTIAL_COMPLETE,
700            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
701            clazz = MacSpi.class,
702            method = "engineUpdate",
703            args = {byte.class}
704        ),
705        @TestTargetNew(
706            level = TestLevel.PARTIAL_COMPLETE,
707            notes = "Checks functionality.",
708            method = "update",
709            args = {byte[].class, int.class, int.class}
710        ),
711        @TestTargetNew(
712            level = TestLevel.PARTIAL_COMPLETE,
713            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
714            clazz = MacSpi.class,
715            method = "engineUpdate",
716            args = {byte[].class, int.class, int.class}
717        )
718    })
719    public void testMac14() throws NoSuchAlgorithmException,
720            NoSuchProviderException, IllegalArgumentException, IllegalStateException,
721            InvalidKeyException {
722        if (!DEFSupported) {
723            fail(NotSupportedMsg);
724            return;
725        }
726        Mac [] macs = createMacs();
727        assertNotNull("Mac objects were not created", macs);
728        byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
729        byte [] upd1 = {(byte)0, (byte)1, (byte)5, (byte)4, (byte)3, (byte)2};
730        byte [] upd2 = {(byte)5, (byte)4, (byte)3, (byte)2};
731        byte [] res1;
732        byte [] res2;
733        SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
734        for (int i = 0; i < macs.length; i++) {
735            macs[i].init(scs);
736            macs[i].update(upd1, 2, 4);
737            res1 = macs[i].doFinal();
738            macs[i].init(scs);
739            macs[i].update(upd2);
740            res2 = macs[i].doFinal();
741            assertEquals("Results are not the same", res1.length, res2.length);
742            for(int t = 0; t < res1.length; t++) {
743                assertEquals("Results are not the same", res1[t], res2[t]);
744            }
745            macs[i].init(scs);
746            macs[i].update((byte)5);
747            res1 = macs[i].doFinal();
748            macs[i].init(scs);
749            macs[i].update(upd1,2,1);
750            res2 = macs[i].doFinal();
751            assertEquals("Results are not the same", res1.length, res2.length);
752            for(int t = 0; t < res1.length; t++) {
753                assertEquals("Results are not the same", res1[t], res2[t]);
754            }
755        }
756    }
757    /**
758     * Test for <code>clone()</code> method
759     * Assertion: returns Mac object or throws CloneNotSupportedException
760     */
761    @TestTargetNew(
762        level = TestLevel.COMPLETE,
763        notes = "",
764        method = "clone",
765        args = {}
766    )
767    public void testMacClone() throws NoSuchAlgorithmException, CloneNotSupportedException {
768        if (!DEFSupported) {
769            fail(NotSupportedMsg);
770            return;
771        }
772        Mac [] macs = createMacs();
773        assertNotNull("Mac objects were not created", macs);
774        for (int i = 0; i < macs.length; i++) {
775            try {
776                Mac mac1 = (Mac) macs[i].clone();
777                assertEquals(mac1.getAlgorithm(), macs[i].getAlgorithm());
778                assertEquals(mac1.getProvider(), macs[i].getProvider());
779                assertFalse(macs[i].equals(mac1));
780            } catch (CloneNotSupportedException e) {
781            }
782        }
783    }
784    /**
785     * Test for
786     * <code>init(Key key, AlgorithmParameterSpec params)</code>
787     * <code>init(Key key)</code>
788     * methods
789     * Assertion: throws InvalidKeyException and InvalidAlgorithmParameterException
790     * when parameters are not appropriate
791     */
792    @TestTargets({
793        @TestTargetNew(
794            level = TestLevel.COMPLETE,
795            notes = "Checks exceptions",
796            method = "init",
797            args = {java.security.Key.class}
798        ),
799        @TestTargetNew(
800            level = TestLevel.COMPLETE,
801            notes = "Checks exceptions",
802            method = "init",
803            args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
804        ),
805        @TestTargetNew(
806            level = TestLevel.COMPLETE,
807            notes = "Checks exceptions",
808            clazz = MacSpi.class,
809            method = "engineInit",
810            args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
811        )
812    })
813    public void testInit() throws NoSuchAlgorithmException, NoSuchProviderException,
814            IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
815            InvalidKeyException {
816        if (!DEFSupported) {
817            fail(NotSupportedMsg);
818            return;
819        }
820        Mac [] macs = createMacs();
821        assertNotNull("Mac objects were not created", macs);
822        byte [] b = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
823        SecretKeySpec sks = new SecretKeySpec(b, "SHA1");
824        DHGenParameterSpec algPS = new DHGenParameterSpec(1, 2);
825        PSSParameterSpec algPSS = new PSSParameterSpec(20);
826        SecretKeySpec sks1 = new SecretKeySpec(b, "RSA");
827
828        for (int i = 0; i < macs.length; i++) {
829            macs[i].init(sks);
830            try {
831                macs[i].init(sks1, algPSS);
832                fail("init(..) accepts incorrect AlgorithmParameterSpec parameter");
833            } catch (InvalidAlgorithmParameterException e) {
834            }
835            try {
836                macs[i].init(sks, algPS);
837                fail("init(..) accepts incorrect AlgorithmParameterSpec parameter");
838            } catch (InvalidAlgorithmParameterException e) {
839            }
840
841            try {
842                macs[i].init(null, null);
843                fail("InvalidKeyException must be thrown");
844            } catch (InvalidKeyException e) {
845            }
846
847            try {
848                macs[i].init(null);
849                fail("InvalidKeyException must be thrown");
850            } catch (InvalidKeyException e) {
851            }
852//            macs[i].init(sks, null);
853        }
854    }
855
856    /**
857     * Test for <code>update(ByteBuffer input)</code>
858     * <code>update(byte[] input, int offset, int len)</code>
859     * methods
860     * Assertion: processes Mac; if input is null then do nothing
861     */
862    @TestTargets({
863        @TestTargetNew(
864            level = TestLevel.PARTIAL_COMPLETE,
865            notes = "Checks functionality",
866            method = "update",
867            args = {byte[].class, int.class, int.class}
868        ),
869        @TestTargetNew(
870            level = TestLevel.PARTIAL_COMPLETE,
871            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
872            clazz = MacSpi.class,
873            method = "engineUpdate",
874            args = {byte[].class, int.class, int.class}
875        ),
876        @TestTargetNew(
877            level = TestLevel.PARTIAL_COMPLETE,
878            notes = "Checks functionality",
879            method = "update",
880            args = {java.nio.ByteBuffer.class}
881        )
882    })
883    public void testUpdateByteBuffer01() throws NoSuchAlgorithmException, NoSuchProviderException,
884            IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
885            InvalidKeyException {
886        if (!DEFSupported) {
887            fail(NotSupportedMsg);
888            return;
889        }
890        Mac [] macs = createMacs();
891        assertNotNull("Mac objects were not created", macs);
892        byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
893        SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
894        ByteBuffer byteNull = null;
895        ByteBuffer byteBuff = ByteBuffer.allocate(0);
896        byte [] bb1;
897        byte [] bb2;
898        for (int i = 0; i < macs.length; i++) {
899            macs[i].init(sks);
900            bb1 = macs[i].doFinal();
901            try {
902                macs[i].update(byteNull);
903                fail("IllegalArgumentException must be thrown because buffer is null");
904            } catch (IllegalArgumentException e) {
905            }
906            macs[i].update(byteBuff);
907            bb2 = macs[i].doFinal();
908            for (int t = 0; t < bb1.length; t++) {
909                assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
910            }
911            macs[i].init(sks);
912            bb1 = macs[i].doFinal();
913            macs[i].update(null, 0, 0);
914            bb2 = macs[i].doFinal();
915            for (int t = 0; t < bb1.length; t++) {
916                assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
917            }
918        }
919    }
920    /**
921     * Test for <code>update(ByteBuffer input)</code>
922     * <code>update(byte[] input, int offset, int len)</code>
923     * methods
924     * Assertion: processes Mac
925     */
926    @TestTargets({
927        @TestTargetNew(
928            level = TestLevel.PARTIAL_COMPLETE,
929            notes = "Checks functionality",
930            method = "update",
931            args = {java.nio.ByteBuffer.class}
932        ),
933        @TestTargetNew(
934            level = TestLevel.PARTIAL_COMPLETE,
935            notes = "Checks functionality",
936            method = "update",
937            args = {byte[].class, int.class, int.class}
938        ),
939        @TestTargetNew(
940            level = TestLevel.PARTIAL_COMPLETE,
941            notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
942            clazz = MacSpi.class,
943            method = "engineUpdate",
944            args = {byte[].class, int.class, int.class}
945        )
946    })
947    public void testUpdateByteBuffer02() throws NoSuchAlgorithmException, NoSuchProviderException,
948            IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
949            InvalidKeyException {
950        if (!DEFSupported) {
951            fail(NotSupportedMsg);
952            return;
953        }
954        Mac [] macs = createMacs();
955        assertNotNull("Mac objects were not created", macs);
956        byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
957        SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
958        byte [] bbuf = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1};
959        ByteBuffer byteBuf;
960        byte [] bb1;
961        byte [] bb2;
962        for (int i = 0; i < macs.length; i++) {
963            byteBuf = ByteBuffer.allocate(5);
964            byteBuf.put(bbuf);
965            byteBuf.position(2);
966            macs[i].init(sks);
967            macs[i].update(byteBuf);
968            bb1 = macs[i].doFinal();
969
970            macs[i].init(sks);
971            macs[i].update(bbuf, 2, 3);
972            bb2 = macs[i].doFinal();
973            for (int t = 0; t < bb1.length; t++) {
974                assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
975            }
976        }
977    }
978    /**
979     * Test for <code>clone()</code> method
980     * Assertion: clone if provider is clo
981     */
982    @TestTargetNew(
983        level = TestLevel.COMPLETE,
984        notes = "",
985        method = "clone",
986        args = {}
987    )
988    public void testClone()  {
989        if (!DEFSupported) {
990            fail(NotSupportedMsg);
991            return;
992        }
993        Mac [] macs = createMacs();
994        assertNotNull("Mac objects were not created", macs);
995        Mac res;
996        for (int i = 0; i < macs.length; i++) {
997            try {
998                res = (Mac)macs[i].clone();
999                assertTrue("Object should not be equals", !macs[i].equals(res));
1000                assertEquals("Incorrect class", macs[i].getClass(), res.getClass());
1001            } catch (CloneNotSupportedException e) {
1002            }
1003        }
1004    }
1005    /**
1006     * Test for <code>getMacLength()</code> method
1007     * Assertion: return Mac length
1008     */
1009    @TestTargets({
1010        @TestTargetNew(
1011            level = TestLevel.COMPLETE,
1012            notes = "",
1013            method = "getMacLength",
1014            args = {}
1015        ),
1016        @TestTargetNew(
1017            level = TestLevel.COMPLETE,
1018            notes = "",
1019            clazz = MacSpi.class,
1020            method = "engineGetMacLength",
1021            args = {}
1022        )
1023    })
1024    public void testGetMacLength() {
1025        if (!DEFSupported) {
1026            fail(NotSupportedMsg);
1027            return;
1028        }
1029        Mac [] macs = createMacs();
1030        assertNotNull("Mac objects were not created", macs);
1031        for (int i = 0; i < macs.length; i++) {
1032            assertTrue("Length should be positive", (macs[i].getMacLength() >= 0));
1033        }
1034    }
1035
1036    /**
1037     * Test for <code>reset()</code> method
1038     * Assertion: return Mac length
1039     */
1040    @TestTargets({
1041        @TestTargetNew(
1042            level = TestLevel.COMPLETE,
1043            notes = "",
1044            method = "reset",
1045            args = {}
1046        ),
1047        @TestTargetNew(
1048            level = TestLevel.COMPLETE,
1049            notes = "",
1050            clazz = MacSpi.class,
1051            method = "engineReset",
1052            args = {}
1053        )
1054    })
1055    public void testReset() throws InvalidKeyException {
1056        if (!DEFSupported) {
1057            fail(NotSupportedMsg);
1058            return;
1059        }
1060        Mac [] macs = createMacs();
1061        assertNotNull("Mac objects were not created", macs);
1062        byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
1063        SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
1064        byte [] bbuf = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1};
1065        byte [] bb1;
1066        byte [] bb2;
1067        for (int i = 0; i < macs.length; i++) {
1068            macs[i].init(sks);
1069            bb1 = macs[i].doFinal();
1070            macs[i].reset();
1071            bb2 = macs[i].doFinal();
1072            assertEquals("incorrect result",bb1.length, bb2.length);
1073            for (int t = 0; t < bb1.length; t++) {
1074               assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
1075            }
1076            macs[i].reset();
1077            macs[i].update(bbuf);
1078            bb1 = macs[i].doFinal();
1079            macs[i].reset();
1080            macs[i].update(bbuf, 0, bbuf.length);
1081            bb2 = macs[i].doFinal();
1082            assertEquals("incorrect result",bb1.length, bb2.length);
1083            for (int t = 0; t < bb1.length; t++) {
1084               assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
1085            }
1086        }
1087    }
1088    /**
1089     * Test for <code>Mac</code> constructor
1090     * Assertion: returns Mac object
1091     */
1092    @TestTargetNew(
1093        level = TestLevel.COMPLETE,
1094        notes = "",
1095        method = "Mac",
1096        args = {javax.crypto.MacSpi.class, java.security.Provider.class, java.lang.String.class}
1097    )
1098    public void testMacConstructor() throws NoSuchAlgorithmException,
1099            InvalidKeyException, InvalidAlgorithmParameterException {
1100        if (!DEFSupported) {
1101            fail(NotSupportedMsg);
1102            return;
1103        }
1104        MacSpi spi = new MyMacSpi();
1105        Mac mac = new myMac(spi, defaultProvider, defaultAlgorithm);
1106        assertEquals("Incorrect algorithm", mac.getAlgorithm(),
1107                defaultAlgorithm);
1108        assertEquals("Incorrect provider", mac.getProvider(), defaultProvider);
1109        try {
1110            mac.init(null, null);
1111            fail("Exception should be thrown because init(..) uses incorrect parameters");
1112        } catch (Exception e) {
1113        }
1114        assertEquals("Invalid mac length", mac.getMacLength(), 0);
1115
1116        mac = new myMac(null, null, null);
1117        assertNull("Algorithm must be null", mac.getAlgorithm());
1118        assertNull("Provider must be null", mac.getProvider());
1119        try {
1120            mac.init(null, null);
1121            fail("Exception should be thrown because init(..) uses incorrect parameters");
1122        } catch (Exception e) {
1123        }
1124        try {
1125            mac.getMacLength();
1126            fail("NullPointerException must be thrown");
1127        } catch (NullPointerException e) {
1128        }
1129    }
1130
1131    @TestTargetNew(
1132        level = TestLevel.COMPLETE,
1133        notes = "",
1134        method = "getAlgorithm",
1135        args = {}
1136    )
1137    public void test_getAlgorithm() throws NoSuchAlgorithmException {
1138        Mac mac;
1139        for (int i = 0; i < validValues.length; i++) {
1140            mac = Mac.getInstance(validValues[i]);
1141            assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
1142        }
1143
1144        mac = new Mock_Mac(null, null, null);
1145        assertNull(mac.getAlgorithm());
1146    }
1147
1148    @TestTargetNew(
1149        level = TestLevel.COMPLETE,
1150        notes = "",
1151        method = "getProvider",
1152        args = {}
1153    )
1154    public void test_getProvider() throws NoSuchAlgorithmException {
1155        Mac mac;
1156        for (int i = 0; i < validValues.length; i++) {
1157            mac = Mac.getInstance(validValues[i]);
1158            assertNotNull(mac.getProvider());
1159        }
1160
1161        mac = new Mock_Mac(null, null, null);
1162        assertNull(mac.getProvider());
1163    }
1164
1165    class Mock_Mac extends Mac {
1166        protected Mock_Mac(MacSpi arg0, Provider arg1, String arg2) {
1167            super(arg0, arg1, arg2);
1168        }
1169    }
1170
1171    public static Test suite() {
1172        return new TestSuite(MacTest.class);
1173    }
1174
1175    public static void main(String args[]) {
1176        junit.textui.TestRunner.run(suite());
1177
1178    }
1179}
1180/**
1181 * Additional class for Mac constructor verification
1182 */
1183class myMac extends Mac {
1184
1185    public myMac(MacSpi macSpi, Provider provider,
1186            String algorithm) {
1187        super(macSpi, provider, algorithm);
1188    }
1189}
1190