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