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