AndroidKeyPairGeneratorTest.java revision b9594ce9ebb3f5f303a280f04312ae5754ce3560
1db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root/* 2db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Copyright (C) 2012 The Android Open Source Project 3db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * 4db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * you may not use this file except in compliance with the License. 6db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * You may obtain a copy of the License at 7db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * 8db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 9db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * 10db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Unless required by applicable law or agreed to in writing, software 11db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * See the License for the specific language governing permissions and 14db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * limitations under the License. 15db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 16db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 17db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootpackage android.security; 18db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 19db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.test.AndroidTestCase; 20db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 21db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.io.ByteArrayInputStream; 22db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.math.BigInteger; 23db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.KeyPair; 24db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.PrivateKey; 25db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.PublicKey; 26db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.SecureRandom; 27db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.cert.Certificate; 28db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.cert.CertificateFactory; 29db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.cert.X509Certificate; 30db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.util.Date; 31db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 32db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport javax.security.auth.x500.X500Principal; 33db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 34db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootpublic class AndroidKeyPairGeneratorTest extends AndroidTestCase { 35db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private android.security.KeyStore mAndroidKeyStore; 36db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 37db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private java.security.KeyPairGenerator mGenerator; 38db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 39db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final String TEST_ALIAS_1 = "test1"; 40db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 41db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final String TEST_ALIAS_2 = "test2"; 42db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 43db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1"); 44db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 45db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2"); 46db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 47db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE; 48db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 49db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L); 50db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 51db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final long NOW_MILLIS = System.currentTimeMillis(); 52db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 53db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /* We have to round this off because X509v3 doesn't store milliseconds. */ 54db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L)); 55db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 56db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root @SuppressWarnings("deprecation") 57db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1); 58db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 59db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root @Override 60db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root protected void setUp() throws Exception { 61db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mAndroidKeyStore = android.security.KeyStore.getInstance(); 62db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 63db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertTrue(mAndroidKeyStore.reset()); 64db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 65b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root assertFalse(mAndroidKeyStore.isUnlocked()); 66db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 67db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertTrue(mAndroidKeyStore.password("1111")); 68b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root assertTrue(mAndroidKeyStore.isUnlocked()); 69db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 70db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertEquals(0, mAndroidKeyStore.saw("").length); 71db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 72db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mGenerator = java.security.KeyPairGenerator.getInstance(AndroidKeyPairGenerator.NAME); 73db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 74db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 75db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root public void testKeyPairGenerator_Initialize_Params_Success() throws Exception { 76db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, 77db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS)); 78db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 79db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 80db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root public void testKeyPairGenerator_Initialize_KeySize_Failure() throws Exception { 81db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root try { 82db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mGenerator.initialize(1024); 83db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root fail("KeyPairGenerator should not support setting the key size"); 84db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } catch (IllegalArgumentException success) { 85db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 86db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 87db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 88db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Failure() throws Exception { 89db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root try { 90db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mGenerator.initialize(1024, new SecureRandom()); 91db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root fail("KeyPairGenerator should not support setting the key size"); 92db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } catch (IllegalArgumentException success) { 93db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 94db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 95db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 96db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Failure() throws Exception { 97db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, 98db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS), new SecureRandom()); 99db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 100db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 101db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root public void testKeyPairGenerator_GenerateKeyPair_Success() throws Exception { 102db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, 103db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS)); 104db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 105db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final KeyPair pair = mGenerator.generateKeyPair(); 106db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertNotNull("The KeyPair returned should not be null", pair); 107db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 108db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertKeyPairCorrect(pair, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS); 109db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 110db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 111db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception { 112db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root // Generate the first key 113db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root { 114db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, 115db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS)); 116db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final KeyPair pair1 = mGenerator.generateKeyPair(); 117db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertNotNull("The KeyPair returned should not be null", pair1); 118db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertKeyPairCorrect(pair1, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW, 119db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root NOW_PLUS_10_YEARS); 120db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 121db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 122db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root // Replace the original key 123db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root { 124db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_2, 125db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root TEST_DN_2, TEST_SERIAL_2, NOW, NOW_PLUS_10_YEARS)); 126db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final KeyPair pair2 = mGenerator.generateKeyPair(); 127db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertNotNull("The KeyPair returned should not be null", pair2); 128db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertKeyPairCorrect(pair2, TEST_ALIAS_2, TEST_DN_2, TEST_SERIAL_2, NOW, 129db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root NOW_PLUS_10_YEARS); 130db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 131db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 132db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 133db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private void assertKeyPairCorrect(KeyPair pair, String alias, X500Principal dn, 134db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root BigInteger serial, Date start, Date end) throws Exception { 135db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final PublicKey pubKey = pair.getPublic(); 136db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertNotNull("The PublicKey for the KeyPair should be not null", pubKey); 137db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 138db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final PrivateKey privKey = pair.getPrivate(); 139db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertNotNull("The PrivateKey for the KeyPair should be not null", privKey); 140db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 141db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias); 142db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertNotNull("The user certificate should exist for the generated entry", userCertBytes); 143db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 144db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final CertificateFactory cf = CertificateFactory.getInstance("X.509"); 145db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final Certificate userCert = cf 146db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root .generateCertificate(new ByteArrayInputStream(userCertBytes)); 147db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 148db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate); 149db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 150db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final X509Certificate x509userCert = (X509Certificate) userCert; 151db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 152db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertEquals("PublicKey used to sign certificate should match one returned in KeyPair", 153db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root pubKey, x509userCert.getPublicKey()); 154db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 155db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertEquals("The Subject DN should be the one passed into the params", dn, 156db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root x509userCert.getSubjectDN()); 157db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 158db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertEquals("The Issuer DN should be the same as the Subject DN", dn, 159db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root x509userCert.getIssuerDN()); 160db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 161db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertEquals("The Serial should be the one passed into the params", serial, 162db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root x509userCert.getSerialNumber()); 163db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 164db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertEquals("The notBefore date should be the one passed into the params", start, 165db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root x509userCert.getNotBefore()); 166db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 167db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertEquals("The notAfter date should be the one passed into the params", end, 168db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root x509userCert.getNotAfter()); 169db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 170db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root x509userCert.verify(pubKey); 171db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 172db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final byte[] caCerts = mAndroidKeyStore.get(Credentials.CA_CERTIFICATE + alias); 173db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertNull("A list of CA certificates should not exist for the generated entry", caCerts); 174db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 175db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root final byte[] pubKeyBytes = mAndroidKeyStore.getPubkey(Credentials.USER_PRIVATE_KEY + alias); 176db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root assertNotNull("The keystore should return the public key for the generated key", 177db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root pubKeyBytes); 178db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 179db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root} 180