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