1 /* 2 * Copyright (C) 2012 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 android.security; 18 19 import android.test.AndroidTestCase; 20 21 import java.io.ByteArrayInputStream; 22 import java.math.BigInteger; 23 import java.security.KeyPair; 24 import java.security.PrivateKey; 25 import java.security.PublicKey; 26 import java.security.SecureRandom; 27 import java.security.cert.Certificate; 28 import java.security.cert.CertificateFactory; 29 import java.security.cert.X509Certificate; 30 import java.security.interfaces.DSAParams; 31 import java.security.interfaces.DSAPublicKey; 32 import java.security.interfaces.ECPublicKey; 33 import java.security.interfaces.RSAPublicKey; 34 import java.security.spec.AlgorithmParameterSpec; 35 import java.security.spec.DSAParameterSpec; 36 import java.security.spec.RSAKeyGenParameterSpec; 37 import java.text.SimpleDateFormat; 38 import java.util.Date; 39 40 import javax.security.auth.x500.X500Principal; 41 42 public class AndroidKeyPairGeneratorTest extends AndroidTestCase { 43 private android.security.KeyStore mAndroidKeyStore; 44 45 private java.security.KeyPairGenerator mGenerator; 46 47 private static final String TEST_ALIAS_1 = "test1"; 48 49 private static final String TEST_ALIAS_2 = "test2"; 50 51 private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1"); 52 53 private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2"); 54 55 private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE; 56 57 private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L); 58 59 private static final long NOW_MILLIS = System.currentTimeMillis(); 60 61 /* We have to round this off because X509v3 doesn't store milliseconds. */ 62 private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L)); 63 64 @SuppressWarnings("deprecation") 65 private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1); 66 67 @Override 68 protected void setUp() throws Exception { 69 mAndroidKeyStore = android.security.KeyStore.getInstance(); 70 71 assertTrue(mAndroidKeyStore.reset()); 72 73 assertFalse(mAndroidKeyStore.isUnlocked()); 74 75 mGenerator = java.security.KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); 76 } 77 78 private void setupPassword() { 79 assertTrue(mAndroidKeyStore.password("1111")); 80 assertTrue(mAndroidKeyStore.isUnlocked()); 81 82 String[] aliases = mAndroidKeyStore.saw(""); 83 assertNotNull(aliases); 84 assertEquals(0, aliases.length); 85 } 86 87 public void testKeyPairGenerator_Initialize_Params_Encrypted_Success() throws Exception { 88 setupPassword(); 89 90 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 91 .setAlias(TEST_ALIAS_1) 92 .setSubject(TEST_DN_1) 93 .setSerialNumber(TEST_SERIAL_1) 94 .setStartDate(NOW) 95 .setEndDate(NOW_PLUS_10_YEARS) 96 .setEncryptionRequired() 97 .build()); 98 } 99 100 public void testKeyPairGenerator_Initialize_KeySize_Encrypted_Failure() throws Exception { 101 setupPassword(); 102 103 try { 104 mGenerator.initialize(1024); 105 fail("KeyPairGenerator should not support setting the key size"); 106 } catch (IllegalArgumentException success) { 107 } 108 } 109 110 public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Encrypted_Failure() 111 throws Exception { 112 setupPassword(); 113 114 try { 115 mGenerator.initialize(1024, new SecureRandom()); 116 fail("KeyPairGenerator should not support setting the key size"); 117 } catch (IllegalArgumentException success) { 118 } 119 } 120 121 public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Encrypted_Failure() 122 throws Exception { 123 setupPassword(); 124 125 mGenerator.initialize( 126 new KeyPairGeneratorSpec.Builder(getContext()) 127 .setAlias(TEST_ALIAS_1) 128 .setKeyType("RSA") 129 .setKeySize(1024) 130 .setSubject(TEST_DN_1) 131 .setSerialNumber(TEST_SERIAL_1) 132 .setStartDate(NOW) 133 .setEndDate(NOW_PLUS_10_YEARS) 134 .setEncryptionRequired() 135 .build(), 136 new SecureRandom()); 137 } 138 139 public void testKeyPairGenerator_GenerateKeyPair_Encrypted_Success() throws Exception { 140 setupPassword(); 141 142 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 143 .setAlias(TEST_ALIAS_1) 144 .setSubject(TEST_DN_1) 145 .setSerialNumber(TEST_SERIAL_1) 146 .setStartDate(NOW) 147 .setEndDate(NOW_PLUS_10_YEARS) 148 .setEncryptionRequired() 149 .build()); 150 151 final KeyPair pair = mGenerator.generateKeyPair(); 152 assertNotNull("The KeyPair returned should not be null", pair); 153 154 assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW, 155 NOW_PLUS_10_YEARS); 156 } 157 158 public void testKeyPairGenerator_GenerateKeyPair_DSA_Unencrypted_Success() throws Exception { 159 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 160 .setAlias(TEST_ALIAS_1) 161 .setKeyType("DSA") 162 .setSubject(TEST_DN_1) 163 .setSerialNumber(TEST_SERIAL_1) 164 .setStartDate(NOW) 165 .setEndDate(NOW_PLUS_10_YEARS) 166 .build()); 167 168 final KeyPair pair = mGenerator.generateKeyPair(); 169 assertNotNull("The KeyPair returned should not be null", pair); 170 171 assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 1024, null, TEST_DN_1, TEST_SERIAL_1, NOW, 172 NOW_PLUS_10_YEARS); 173 } 174 175 public void testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success() 176 throws Exception { 177 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 178 .setAlias(TEST_ALIAS_1) 179 .setKeyType("DSA") 180 .setKeySize(2048) 181 .setSubject(TEST_DN_1) 182 .setSerialNumber(TEST_SERIAL_1) 183 .setStartDate(NOW) 184 .setEndDate(NOW_PLUS_10_YEARS) 185 .build()); 186 187 final KeyPair pair = mGenerator.generateKeyPair(); 188 assertNotNull("The KeyPair returned should not be null", pair); 189 190 assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW, 191 NOW_PLUS_10_YEARS); 192 } 193 194 public void testKeyPairGenerator_GenerateKeyPair_DSA_SpecifiedParams_Unencrypted_Success() 195 throws Exception { 196 /* 197 * generated using: openssl dsaparam -C 2048 198 */ 199 BigInteger p = new BigInteger(1, new byte[] { 200 (byte) 0xC0, (byte) 0x3D, (byte) 0x86, (byte) 0x09, (byte) 0xCA, (byte) 0x8C, 201 (byte) 0x37, (byte) 0xCA, (byte) 0xCC, (byte) 0x4A, (byte) 0x81, (byte) 0xBD, 202 (byte) 0xD8, (byte) 0x50, (byte) 0x77, (byte) 0xCD, (byte) 0xDD, (byte) 0x32, 203 (byte) 0x0B, (byte) 0x43, (byte) 0xBF, (byte) 0x42, (byte) 0x06, (byte) 0x5A, 204 (byte) 0x3D, (byte) 0x18, (byte) 0x50, (byte) 0x47, (byte) 0x79, (byte) 0xE1, 205 (byte) 0x5B, (byte) 0x86, (byte) 0x03, (byte) 0xB9, (byte) 0x28, (byte) 0x9C, 206 (byte) 0x18, (byte) 0xA9, (byte) 0xF5, (byte) 0xD6, (byte) 0xF4, (byte) 0x94, 207 (byte) 0x5B, (byte) 0x87, (byte) 0x58, (byte) 0xCA, (byte) 0xB2, (byte) 0x1E, 208 (byte) 0xFC, (byte) 0xED, (byte) 0x37, (byte) 0xC3, (byte) 0x49, (byte) 0xAC, 209 (byte) 0xFA, (byte) 0x46, (byte) 0xDB, (byte) 0x7A, (byte) 0x50, (byte) 0x96, 210 (byte) 0xCF, (byte) 0x52, (byte) 0xD7, (byte) 0x4E, (byte) 0xEB, (byte) 0x26, 211 (byte) 0x41, (byte) 0xA2, (byte) 0x6F, (byte) 0x99, (byte) 0x80, (byte) 0x9F, 212 (byte) 0x0F, (byte) 0x0A, (byte) 0xA8, (byte) 0x0D, (byte) 0xAC, (byte) 0xAB, 213 (byte) 0xEF, (byte) 0x7D, (byte) 0xE7, (byte) 0x4C, (byte) 0xF1, (byte) 0x88, 214 (byte) 0x44, (byte) 0xC9, (byte) 0x17, (byte) 0xD0, (byte) 0xBB, (byte) 0xE2, 215 (byte) 0x01, (byte) 0x8C, (byte) 0xC1, (byte) 0x02, (byte) 0x1D, (byte) 0x3C, 216 (byte) 0x15, (byte) 0xB7, (byte) 0x41, (byte) 0x30, (byte) 0xD8, (byte) 0x11, 217 (byte) 0xBD, (byte) 0x6A, (byte) 0x2A, (byte) 0x0D, (byte) 0x36, (byte) 0x44, 218 (byte) 0x9C, (byte) 0x3F, (byte) 0x32, (byte) 0xE2, (byte) 0x1C, (byte) 0xFB, 219 (byte) 0xE3, (byte) 0xFF, (byte) 0xCC, (byte) 0x1A, (byte) 0x72, (byte) 0x38, 220 (byte) 0x37, (byte) 0x69, (byte) 0x5E, (byte) 0x35, (byte) 0x73, (byte) 0xE1, 221 (byte) 0x1E, (byte) 0x74, (byte) 0x35, (byte) 0x44, (byte) 0x07, (byte) 0xB5, 222 (byte) 0x2F, (byte) 0x0B, (byte) 0x60, (byte) 0xF4, (byte) 0xA9, (byte) 0xE0, 223 (byte) 0x81, (byte) 0xB2, (byte) 0xCD, (byte) 0x8B, (byte) 0x82, (byte) 0x76, 224 (byte) 0x7F, (byte) 0xD4, (byte) 0x17, (byte) 0x32, (byte) 0x86, (byte) 0x98, 225 (byte) 0x7C, (byte) 0x85, (byte) 0x66, (byte) 0xF6, (byte) 0x77, (byte) 0xED, 226 (byte) 0x8B, (byte) 0x1A, (byte) 0x52, (byte) 0x16, (byte) 0xDA, (byte) 0x1C, 227 (byte) 0xA7, (byte) 0x16, (byte) 0x79, (byte) 0x20, (byte) 0x1C, (byte) 0x99, 228 (byte) 0x5F, (byte) 0x12, (byte) 0x66, (byte) 0x15, (byte) 0x9F, (byte) 0xE5, 229 (byte) 0x73, (byte) 0xA9, (byte) 0x61, (byte) 0xBA, (byte) 0xA7, (byte) 0x23, 230 (byte) 0x93, (byte) 0x77, (byte) 0xB5, (byte) 0xF6, (byte) 0xEC, (byte) 0x13, 231 (byte) 0xBF, (byte) 0x95, (byte) 0x60, (byte) 0x78, (byte) 0x84, (byte) 0xE3, 232 (byte) 0x44, (byte) 0xEC, (byte) 0x74, (byte) 0xC2, (byte) 0xCB, (byte) 0xD4, 233 (byte) 0x70, (byte) 0xC5, (byte) 0x7B, (byte) 0xF8, (byte) 0x07, (byte) 0x3B, 234 (byte) 0xEB, (byte) 0x9F, (byte) 0xC9, (byte) 0x7D, (byte) 0xE0, (byte) 0xA5, 235 (byte) 0xBA, (byte) 0x68, (byte) 0x7B, (byte) 0xF4, (byte) 0x70, (byte) 0x40, 236 (byte) 0xAE, (byte) 0xE9, (byte) 0x65, (byte) 0xEE, (byte) 0x5B, (byte) 0x71, 237 (byte) 0x36, (byte) 0x0B, (byte) 0xB0, (byte) 0xA2, (byte) 0x98, (byte) 0x7D, 238 (byte) 0xE3, (byte) 0x24, (byte) 0x95, (byte) 0x2B, (byte) 0xC2, (byte) 0x0A, 239 (byte) 0x78, (byte) 0x3D, (byte) 0xCC, (byte) 0x3A, (byte) 0xEE, (byte) 0xED, 240 (byte) 0x48, (byte) 0xEB, (byte) 0xA3, (byte) 0x78, (byte) 0xA8, (byte) 0x9D, 241 (byte) 0x0A, (byte) 0x8F, (byte) 0x9E, (byte) 0x59, (byte) 0x2C, (byte) 0x44, 242 (byte) 0xB5, (byte) 0xF9, (byte) 0x53, (byte) 0x43, 243 }); 244 245 BigInteger q = new BigInteger(1, new byte[] { 246 (byte) 0xA1, (byte) 0x9B, (byte) 0x1D, (byte) 0xC0, (byte) 0xE3, (byte) 0xF6, 247 (byte) 0x4A, (byte) 0x35, (byte) 0xE1, (byte) 0x8A, (byte) 0x43, (byte) 0xC2, 248 (byte) 0x9C, (byte) 0xF9, (byte) 0x52, (byte) 0x8F, (byte) 0x94, (byte) 0xA1, 249 (byte) 0x12, (byte) 0x11, (byte) 0xDB, (byte) 0x9A, (byte) 0xB6, (byte) 0x35, 250 (byte) 0x56, (byte) 0x26, (byte) 0x60, (byte) 0x89, (byte) 0x11, (byte) 0xAC, 251 (byte) 0xA8, (byte) 0xE5, 252 }); 253 254 BigInteger g = new BigInteger(1, new byte[] { 255 (byte) 0xA1, (byte) 0x5C, (byte) 0x57, (byte) 0x15, (byte) 0xC3, (byte) 0xD9, 256 (byte) 0xD7, (byte) 0x41, (byte) 0x89, (byte) 0xD6, (byte) 0xB8, (byte) 0x7B, 257 (byte) 0xF3, (byte) 0xE0, (byte) 0xB3, (byte) 0xC5, (byte) 0xD1, (byte) 0xAA, 258 (byte) 0xF9, (byte) 0x55, (byte) 0x48, (byte) 0xF1, (byte) 0xDA, (byte) 0xE8, 259 (byte) 0x6F, (byte) 0x51, (byte) 0x05, (byte) 0xB2, (byte) 0xC9, (byte) 0x64, 260 (byte) 0xDA, (byte) 0x5F, (byte) 0xD4, (byte) 0xAA, (byte) 0xFD, (byte) 0x67, 261 (byte) 0xE0, (byte) 0x10, (byte) 0x2C, (byte) 0x1F, (byte) 0x03, (byte) 0x10, 262 (byte) 0xD4, (byte) 0x4B, (byte) 0x20, (byte) 0x82, (byte) 0x2B, (byte) 0x04, 263 (byte) 0xF9, (byte) 0x09, (byte) 0xAE, (byte) 0x28, (byte) 0x3D, (byte) 0x9B, 264 (byte) 0xFF, (byte) 0x87, (byte) 0x76, (byte) 0xCD, (byte) 0xF0, (byte) 0x11, 265 (byte) 0xB7, (byte) 0xEA, (byte) 0xE6, (byte) 0xCD, (byte) 0x60, (byte) 0xD3, 266 (byte) 0x8C, (byte) 0x74, (byte) 0xD3, (byte) 0x45, (byte) 0x63, (byte) 0x69, 267 (byte) 0x3F, (byte) 0x1D, (byte) 0x31, (byte) 0x25, (byte) 0x49, (byte) 0x97, 268 (byte) 0x4B, (byte) 0x73, (byte) 0x34, (byte) 0x12, (byte) 0x73, (byte) 0x27, 269 (byte) 0x4C, (byte) 0xDA, (byte) 0xF3, (byte) 0x08, (byte) 0xA8, (byte) 0xA9, 270 (byte) 0x27, (byte) 0xE4, (byte) 0xB8, (byte) 0xD6, (byte) 0xB5, (byte) 0xC4, 271 (byte) 0x18, (byte) 0xED, (byte) 0xBD, (byte) 0x6F, (byte) 0xA2, (byte) 0x36, 272 (byte) 0xA2, (byte) 0x9C, (byte) 0x27, (byte) 0x62, (byte) 0x7F, (byte) 0x93, 273 (byte) 0xD7, (byte) 0x52, (byte) 0xA9, (byte) 0x76, (byte) 0x55, (byte) 0x99, 274 (byte) 0x00, (byte) 0x5B, (byte) 0xC2, (byte) 0xB9, (byte) 0x18, (byte) 0xAC, 275 (byte) 0x6B, (byte) 0x83, (byte) 0x0D, (byte) 0xA1, (byte) 0xC5, (byte) 0x01, 276 (byte) 0x1A, (byte) 0xE5, (byte) 0x4D, (byte) 0x2F, (byte) 0xCF, (byte) 0x5D, 277 (byte) 0xB2, (byte) 0xE7, (byte) 0xC7, (byte) 0xCB, (byte) 0x2C, (byte) 0xFF, 278 (byte) 0x51, (byte) 0x1B, (byte) 0x9D, (byte) 0xA4, (byte) 0x05, (byte) 0xEB, 279 (byte) 0x17, (byte) 0xD8, (byte) 0x97, (byte) 0x9D, (byte) 0x0C, (byte) 0x59, 280 (byte) 0x92, (byte) 0x8A, (byte) 0x03, (byte) 0x34, (byte) 0xFD, (byte) 0x16, 281 (byte) 0x0F, (byte) 0x2A, (byte) 0xF9, (byte) 0x7D, (byte) 0xC3, (byte) 0x41, 282 (byte) 0x0D, (byte) 0x06, (byte) 0x5A, (byte) 0x4B, (byte) 0x34, (byte) 0xD5, 283 (byte) 0xF5, (byte) 0x09, (byte) 0x1C, (byte) 0xCE, (byte) 0xA7, (byte) 0x19, 284 (byte) 0x6D, (byte) 0x04, (byte) 0x53, (byte) 0x71, (byte) 0xCC, (byte) 0x84, 285 (byte) 0xA0, (byte) 0xB2, (byte) 0xA0, (byte) 0x68, (byte) 0xA3, (byte) 0x40, 286 (byte) 0xC0, (byte) 0x67, (byte) 0x38, (byte) 0x96, (byte) 0x73, (byte) 0x2E, 287 (byte) 0x8E, (byte) 0x2A, (byte) 0x9D, (byte) 0x56, (byte) 0xE9, (byte) 0xAC, 288 (byte) 0xC7, (byte) 0xEC, (byte) 0x84, (byte) 0x7F, (byte) 0xFC, (byte) 0xE0, 289 (byte) 0x69, (byte) 0x03, (byte) 0x8B, (byte) 0x48, (byte) 0x64, (byte) 0x76, 290 (byte) 0x85, (byte) 0xA5, (byte) 0x10, (byte) 0xD9, (byte) 0x31, (byte) 0xC3, 291 (byte) 0x8B, (byte) 0x07, (byte) 0x48, (byte) 0x62, (byte) 0xF6, (byte) 0x68, 292 (byte) 0xF2, (byte) 0x96, (byte) 0xB2, (byte) 0x18, (byte) 0x5B, (byte) 0xFF, 293 (byte) 0x6D, (byte) 0xD1, (byte) 0x6B, (byte) 0xF5, (byte) 0xFD, (byte) 0x81, 294 (byte) 0xF1, (byte) 0xFD, (byte) 0x04, (byte) 0xF0, (byte) 0x9F, (byte) 0xB7, 295 (byte) 0x08, (byte) 0x95, (byte) 0x57, (byte) 0x48, (byte) 0x07, (byte) 0x00, 296 (byte) 0x52, (byte) 0xEC, (byte) 0x75, (byte) 0x91, (byte) 0x02, (byte) 0x11, 297 (byte) 0xA3, (byte) 0x64, (byte) 0x26, (byte) 0xCA, 298 }); 299 300 AlgorithmParameterSpec spec = new DSAParameterSpec(p, q, g); 301 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 302 .setAlias(TEST_ALIAS_1) 303 .setKeyType("DSA") 304 .setKeySize(2048) 305 .setAlgorithmParameterSpec(spec) 306 .setSubject(TEST_DN_1) 307 .setSerialNumber(TEST_SERIAL_1) 308 .setStartDate(NOW) 309 .setEndDate(NOW_PLUS_10_YEARS) 310 .build()); 311 312 final KeyPair pair = mGenerator.generateKeyPair(); 313 assertNotNull("The KeyPair returned should not be null", pair); 314 315 assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, spec, TEST_DN_1, TEST_SERIAL_1, NOW, 316 NOW_PLUS_10_YEARS); 317 } 318 319 public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception { 320 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 321 .setAlias(TEST_ALIAS_1) 322 .setKeyType("EC") 323 .setSubject(TEST_DN_1) 324 .setSerialNumber(TEST_SERIAL_1) 325 .setStartDate(NOW) 326 .setEndDate(NOW_PLUS_10_YEARS) 327 .build()); 328 329 final KeyPair pair = mGenerator.generateKeyPair(); 330 assertNotNull("The KeyPair returned should not be null", pair); 331 332 assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW, 333 NOW_PLUS_10_YEARS); 334 } 335 336 public void testKeyPairGenerator_GenerateKeyPair_EC_P521_Unencrypted_Success() throws Exception { 337 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 338 .setAlias(TEST_ALIAS_1) 339 .setKeyType("EC") 340 .setKeySize(521) 341 .setSubject(TEST_DN_1) 342 .setSerialNumber(TEST_SERIAL_1) 343 .setStartDate(NOW) 344 .setEndDate(NOW_PLUS_10_YEARS) 345 .build()); 346 347 final KeyPair pair = mGenerator.generateKeyPair(); 348 assertNotNull("The KeyPair returned should not be null", pair); 349 350 assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 521, null, TEST_DN_1, TEST_SERIAL_1, NOW, 351 NOW_PLUS_10_YEARS); 352 } 353 354 public void testKeyPairGenerator_GenerateKeyPair_RSA_Unencrypted_Success() throws Exception { 355 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 356 .setAlias(TEST_ALIAS_1) 357 .setSubject(TEST_DN_1) 358 .setSerialNumber(TEST_SERIAL_1) 359 .setStartDate(NOW) 360 .setEndDate(NOW_PLUS_10_YEARS) 361 .build()); 362 363 final KeyPair pair = mGenerator.generateKeyPair(); 364 assertNotNull("The KeyPair returned should not be null", pair); 365 366 assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW, 367 NOW_PLUS_10_YEARS); 368 } 369 370 public void testKeyPairGenerator_GenerateKeyPair_RSA_WithParams_Unencrypted_Success() 371 throws Exception { 372 AlgorithmParameterSpec spec = new RSAKeyGenParameterSpec(1024, BigInteger.valueOf(3L)); 373 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 374 .setAlias(TEST_ALIAS_1) 375 .setKeySize(1024) 376 .setAlgorithmParameterSpec(spec) 377 .setSubject(TEST_DN_1) 378 .setSerialNumber(TEST_SERIAL_1) 379 .setStartDate(NOW) 380 .setEndDate(NOW_PLUS_10_YEARS) 381 .build()); 382 383 final KeyPair pair = mGenerator.generateKeyPair(); 384 assertNotNull("The KeyPair returned should not be null", pair); 385 386 assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 1024, spec, TEST_DN_1, TEST_SERIAL_1, NOW, 387 NOW_PLUS_10_YEARS); 388 } 389 390 public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception { 391 // Generate the first key 392 { 393 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 394 .setAlias(TEST_ALIAS_1) 395 .setSubject(TEST_DN_1) 396 .setSerialNumber(TEST_SERIAL_1) 397 .setStartDate(NOW) 398 .setEndDate(NOW_PLUS_10_YEARS) 399 .build()); 400 final KeyPair pair1 = mGenerator.generateKeyPair(); 401 assertNotNull("The KeyPair returned should not be null", pair1); 402 assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, 403 NOW, NOW_PLUS_10_YEARS); 404 } 405 406 // Replace the original key 407 { 408 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 409 .setAlias(TEST_ALIAS_2) 410 .setSubject(TEST_DN_2) 411 .setSerialNumber(TEST_SERIAL_2) 412 .setStartDate(NOW) 413 .setEndDate(NOW_PLUS_10_YEARS) 414 .build()); 415 final KeyPair pair2 = mGenerator.generateKeyPair(); 416 assertNotNull("The KeyPair returned should not be null", pair2); 417 assertKeyPairCorrect(pair2, TEST_ALIAS_2, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2, 418 NOW, NOW_PLUS_10_YEARS); 419 } 420 } 421 422 public void testKeyPairGenerator_GenerateKeyPair_Replaced_UnencryptedToEncrypted_Success() 423 throws Exception { 424 // Generate the first key 425 { 426 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 427 .setAlias(TEST_ALIAS_1) 428 .setSubject(TEST_DN_1) 429 .setSerialNumber(TEST_SERIAL_1) 430 .setStartDate(NOW) 431 .setEndDate(NOW_PLUS_10_YEARS) 432 .build()); 433 final KeyPair pair1 = mGenerator.generateKeyPair(); 434 assertNotNull("The KeyPair returned should not be null", pair1); 435 assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, 436 NOW, NOW_PLUS_10_YEARS); 437 } 438 439 // Attempt to replace previous key 440 { 441 mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 442 .setAlias(TEST_ALIAS_1) 443 .setSubject(TEST_DN_2) 444 .setSerialNumber(TEST_SERIAL_2) 445 .setStartDate(NOW) 446 .setEndDate(NOW_PLUS_10_YEARS) 447 .setEncryptionRequired() 448 .build()); 449 try { 450 mGenerator.generateKeyPair(); 451 fail("Should not be able to generate encrypted key while not initialized"); 452 } catch (IllegalStateException expected) { 453 } 454 455 assertTrue(mAndroidKeyStore.password("1111")); 456 assertTrue(mAndroidKeyStore.isUnlocked()); 457 458 final KeyPair pair2 = mGenerator.generateKeyPair(); 459 assertNotNull("The KeyPair returned should not be null", pair2); 460 assertKeyPairCorrect(pair2, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2, 461 NOW, NOW_PLUS_10_YEARS); 462 } 463 } 464 465 private void assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize, 466 AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end) 467 throws Exception { 468 final PublicKey pubKey = pair.getPublic(); 469 assertNotNull("The PublicKey for the KeyPair should be not null", pubKey); 470 assertEquals(keyType, pubKey.getAlgorithm()); 471 472 if ("DSA".equalsIgnoreCase(keyType)) { 473 DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey; 474 DSAParams actualParams = dsaPubKey.getParams(); 475 assertEquals(keySize, (actualParams.getP().bitLength() + 7) & ~7); 476 if (spec != null) { 477 DSAParameterSpec expectedParams = (DSAParameterSpec) spec; 478 assertEquals(expectedParams.getP(), actualParams.getP()); 479 assertEquals(expectedParams.getQ(), actualParams.getQ()); 480 assertEquals(expectedParams.getG(), actualParams.getG()); 481 } 482 } else if ("EC".equalsIgnoreCase(keyType)) { 483 assertEquals("Curve should be what was specified during initialization", keySize, 484 ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize()); 485 } else if ("RSA".equalsIgnoreCase(keyType)) { 486 RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey; 487 assertEquals("Modulus size should be what is specified during initialization", 488 (keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7); 489 if (spec != null) { 490 RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec; 491 assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7); 492 assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent()); 493 } 494 } 495 496 final PrivateKey privKey = pair.getPrivate(); 497 assertNotNull("The PrivateKey for the KeyPair should be not null", privKey); 498 assertEquals(keyType, privKey.getAlgorithm()); 499 500 final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias); 501 assertNotNull("The user certificate should exist for the generated entry", userCertBytes); 502 503 final CertificateFactory cf = CertificateFactory.getInstance("X.509"); 504 final Certificate userCert = cf 505 .generateCertificate(new ByteArrayInputStream(userCertBytes)); 506 507 assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate); 508 509 final X509Certificate x509userCert = (X509Certificate) userCert; 510 511 assertEquals("PublicKey used to sign certificate should match one returned in KeyPair", 512 pubKey, x509userCert.getPublicKey()); 513 514 assertEquals("The Subject DN should be the one passed into the params", dn, 515 x509userCert.getSubjectDN()); 516 517 assertEquals("The Issuer DN should be the same as the Subject DN", dn, 518 x509userCert.getIssuerDN()); 519 520 assertEquals("The Serial should be the one passed into the params", serial, 521 x509userCert.getSerialNumber()); 522 523 assertDateEquals("The notBefore date should be the one passed into the params", start, 524 x509userCert.getNotBefore()); 525 526 assertDateEquals("The notAfter date should be the one passed into the params", end, 527 x509userCert.getNotAfter()); 528 529 x509userCert.verify(pubKey); 530 531 final byte[] caCerts = mAndroidKeyStore.get(Credentials.CA_CERTIFICATE + alias); 532 assertNull("A list of CA certificates should not exist for the generated entry", caCerts); 533 534 final byte[] pubKeyBytes = mAndroidKeyStore.getPubkey(Credentials.USER_PRIVATE_KEY + alias); 535 assertNotNull("The keystore should return the public key for the generated key", 536 pubKeyBytes); 537 } 538 539 private static void assertDateEquals(String message, Date date1, Date date2) throws Exception { 540 SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss"); 541 542 String result1 = formatter.format(date1); 543 String result2 = formatter.format(date2); 544 545 assertEquals(message, result1, result2); 546 } 547 } 548