Home | History | Annotate | Download | only in crypto
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package org.conscrypt.javax.crypto;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertNotNull;
     21 
     22 import java.security.Provider;
     23 import java.security.SecureRandom;
     24 import java.security.Security;
     25 import java.util.ArrayList;
     26 import java.util.HashMap;
     27 import java.util.List;
     28 import java.util.Map;
     29 import java.util.Set;
     30 import javax.crypto.KeyGenerator;
     31 import javax.crypto.SecretKey;
     32 import libcore.java.security.StandardNames;
     33 import org.conscrypt.TestUtils;
     34 import org.junit.AfterClass;
     35 import org.junit.BeforeClass;
     36 import org.junit.Test;
     37 import org.junit.runner.RunWith;
     38 import org.junit.runners.JUnit4;
     39 import dalvik.system.VMRuntime;
     40 import sun.security.jca.Providers;
     41 
     42 @RunWith(JUnit4.class)
     43 public class KeyGeneratorTest {
     44 
     45     // BEGIN Android-Added: Allow access to deprecated BC algorithms.
     46     // Allow access to deprecated BC algorithms in this test, so we can ensure they
     47     // continue to work
     48     @BeforeClass
     49     public static void enableDeprecatedAlgorithms() {
     50         Providers.setMaximumAllowableApiLevelForBcDeprecation(
     51                 VMRuntime.getRuntime().getTargetSdkVersion());
     52     }
     53 
     54     @AfterClass
     55     public static void restoreDeprecatedAlgorithms() {
     56         Providers.setMaximumAllowableApiLevelForBcDeprecation(
     57                 Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
     58     }
     59     // END Android-Added: Allow access to deprecated BC algorithms.
     60 
     61     private static boolean isUnsupported(KeyGenerator kg) {
     62         // Don't bother testing "Sun..." KeyGenerators or BC outside of Android
     63         return kg.getProvider().getName().startsWith("Sun")
     64                 || (StandardNames.IS_RI && kg.getProvider().getName().equals("BC"));
     65     }
     66 
     67     @BeforeClass
     68     public static void setUp() {
     69         TestUtils.assumeAllowsUnsignedCrypto();
     70     }
     71 
     72     @Test
     73     public void test_getInstance() throws Exception {
     74         Provider[] providers = Security.getProviders();
     75         for (Provider provider : providers) {
     76             Set<Provider.Service> services = provider.getServices();
     77             for (Provider.Service service : services) {
     78                 String type = service.getType();
     79                 if (!type.equals("KeyGenerator")) {
     80                     continue;
     81                 }
     82 
     83                 // Do not test AndroidKeyStore's KeyGenerator. It cannot be initialized without
     84                 // providing AndroidKeyStore-specific algorithm parameters.
     85                 // It's OKish not to test AndroidKeyStore's KeyGenerator here because it's tested
     86                 // by cts/tests/test/keystore.
     87                 if ("AndroidKeyStore".equals(provider.getName())) {
     88                     continue;
     89                 }
     90 
     91                 String algorithm = service.getAlgorithm();
     92                 try {
     93                     // KeyGenerator.getInstance(String)
     94                     KeyGenerator kg1 = KeyGenerator.getInstance(algorithm);
     95                     assertEquals(algorithm, kg1.getAlgorithm());
     96                     test_KeyGenerator(kg1);
     97 
     98                     // KeyGenerator.getInstance(String, Provider)
     99                     KeyGenerator kg2 = KeyGenerator.getInstance(algorithm, provider);
    100                     assertEquals(algorithm, kg2.getAlgorithm());
    101                     assertEquals(provider, kg2.getProvider());
    102                     test_KeyGenerator(kg2);
    103 
    104                     // KeyGenerator.getInstance(String, String)
    105                     KeyGenerator kg3 = KeyGenerator.getInstance(algorithm, provider.getName());
    106                     assertEquals(algorithm, kg3.getAlgorithm());
    107                     assertEquals(provider, kg3.getProvider());
    108                     test_KeyGenerator(kg3);
    109                 } catch (Exception e) {
    110                     throw new Exception("Problem testing KeyPairGenerator." + algorithm, e);
    111                 }
    112             }
    113         }
    114     }
    115 
    116     private static final Map<String, List<Integer>> KEY_SIZES
    117             = new HashMap<String, List<Integer>>();
    118     private static void putKeySize(String algorithm, int keySize) {
    119         algorithm = algorithm.toUpperCase();
    120         List<Integer> keySizes = KEY_SIZES.get(algorithm);
    121         if (keySizes == null) {
    122             keySizes = new ArrayList<Integer>();
    123             KEY_SIZES.put(algorithm, keySizes);
    124         }
    125         keySizes.add(keySize);
    126     }
    127     private static List<Integer> getKeySizes(String algorithm) throws Exception {
    128         algorithm = algorithm.toUpperCase();
    129         List<Integer> keySizes = KEY_SIZES.get(algorithm);
    130         if (keySizes == null) {
    131             throw new Exception("Unknown key sizes for KeyGenerator." + algorithm);
    132         }
    133         return keySizes;
    134     }
    135     static {
    136         putKeySize("AES", 128);
    137         putKeySize("AES", 192);
    138         putKeySize("AES", 256);
    139         putKeySize("ARC4", 1024);
    140         putKeySize("ARC4", 40);
    141         putKeySize("ARC4", 41);
    142         putKeySize("ARCFOUR", 1024);
    143         putKeySize("ARCFOUR", 40);
    144         putKeySize("ARCFOUR", 41);
    145         putKeySize("Blowfish", 32);
    146         putKeySize("Blowfish", 32+8);
    147         putKeySize("Blowfish", 448);
    148         putKeySize("ChaCha20", 256);
    149         putKeySize("DES", 56);
    150         putKeySize("DESede", 112);
    151         putKeySize("DESede", 168);
    152         putKeySize("RC2", 40);
    153         putKeySize("RC2", 41);
    154         putKeySize("RC2", 1024);
    155         putKeySize("RC4", 40);
    156         putKeySize("RC4", 41);
    157         putKeySize("RC4", 1024);
    158         putKeySize("HmacMD5", 1);
    159         putKeySize("HmacMD5", 1025);
    160         putKeySize("HmacSHA1", 1);
    161         putKeySize("HmacSHA1", 1025);
    162         putKeySize("HmacSHA224", 40);
    163         putKeySize("HmacSHA224", 1025);
    164         putKeySize("HmacSHA256", 40);
    165         putKeySize("HmacSHA256", 1025);
    166         putKeySize("HmacSHA384", 40);
    167         putKeySize("HmacSHA384", 1025);
    168         putKeySize("HmacSHA512", 40);
    169         putKeySize("HmacSHA512", 1025);
    170     }
    171 
    172     private void test_KeyGenerator(KeyGenerator kg) throws Exception {
    173         if (isUnsupported(kg)) {
    174             return;
    175         }
    176 
    177         kg.init((SecureRandom) null);
    178         test_SecretKey(kg, kg.generateKey());
    179 
    180         kg.init(new SecureRandom());
    181         test_SecretKey(kg, kg.generateKey());
    182 
    183         String algorithm = kg.getAlgorithm();
    184         List<Integer> keySizes = getKeySizes(algorithm);
    185         for (int keySize : keySizes) {
    186             kg.init(keySize);
    187             test_SecretKey(kg, kg.generateKey());
    188 
    189             kg.init(keySize, (SecureRandom) null);
    190             test_SecretKey(kg, kg.generateKey());
    191 
    192             kg.init(keySize, new SecureRandom());
    193             test_SecretKey(kg, kg.generateKey());
    194         }
    195     }
    196 
    197     private void test_SecretKey(KeyGenerator kg, SecretKey sk) throws Exception {
    198         assertNotNull(sk);
    199         assertEquals(kg.getAlgorithm().toUpperCase(), sk.getAlgorithm().toUpperCase());
    200         assertNotNull(sk.getEncoded());
    201         assertNotNull(sk.getFormat());
    202     }
    203 }
    204