• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.util.Date;
31 
32 import javax.security.auth.x500.X500Principal;
33 
34 public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
35     private android.security.KeyStore mAndroidKeyStore;
36 
37     private java.security.KeyPairGenerator mGenerator;
38 
39     private static final String TEST_ALIAS_1 = "test1";
40 
41     private static final String TEST_ALIAS_2 = "test2";
42 
43     private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
44 
45     private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
46 
47     private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
48 
49     private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
50 
51     private static final long NOW_MILLIS = System.currentTimeMillis();
52 
53     /* We have to round this off because X509v3 doesn't store milliseconds. */
54     private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
55 
56     @SuppressWarnings("deprecation")
57     private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
58 
59     @Override
setUp()60     protected void setUp() throws Exception {
61         mAndroidKeyStore = android.security.KeyStore.getInstance();
62 
63         assertTrue(mAndroidKeyStore.reset());
64 
65         assertEquals(android.security.KeyStore.State.UNINITIALIZED, mAndroidKeyStore.state());
66 
67         assertTrue(mAndroidKeyStore.password("1111"));
68 
69         assertEquals(android.security.KeyStore.State.UNLOCKED, mAndroidKeyStore.state());
70 
71         assertEquals(0, mAndroidKeyStore.saw("").length);
72 
73         mGenerator = java.security.KeyPairGenerator.getInstance(AndroidKeyPairGenerator.NAME);
74     }
75 
testKeyPairGenerator_Initialize_Params_Success()76     public void testKeyPairGenerator_Initialize_Params_Success() throws Exception {
77         mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1,
78                 TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS));
79     }
80 
testKeyPairGenerator_Initialize_KeySize_Failure()81     public void testKeyPairGenerator_Initialize_KeySize_Failure() throws Exception {
82         try {
83             mGenerator.initialize(1024);
84             fail("KeyPairGenerator should not support setting the key size");
85         } catch (IllegalArgumentException success) {
86         }
87     }
88 
testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Failure()89     public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Failure() throws Exception {
90         try {
91             mGenerator.initialize(1024, new SecureRandom());
92             fail("KeyPairGenerator should not support setting the key size");
93         } catch (IllegalArgumentException success) {
94         }
95     }
96 
testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Failure()97     public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Failure() throws Exception {
98         mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1,
99                 TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS), new SecureRandom());
100     }
101 
testKeyPairGenerator_GenerateKeyPair_Success()102     public void testKeyPairGenerator_GenerateKeyPair_Success() throws Exception {
103         mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1,
104                 TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS));
105 
106         final KeyPair pair = mGenerator.generateKeyPair();
107         assertNotNull("The KeyPair returned should not be null", pair);
108 
109         assertKeyPairCorrect(pair, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS);
110     }
111 
testKeyPairGenerator_GenerateKeyPair_Replaced_Success()112     public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception {
113         // Generate the first key
114         {
115             mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_1,
116                     TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS));
117             final KeyPair pair1 = mGenerator.generateKeyPair();
118             assertNotNull("The KeyPair returned should not be null", pair1);
119             assertKeyPairCorrect(pair1, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW,
120                     NOW_PLUS_10_YEARS);
121         }
122 
123         // Replace the original key
124         {
125             mGenerator.initialize(new AndroidKeyPairGeneratorSpec(getContext(), TEST_ALIAS_2,
126                     TEST_DN_2, TEST_SERIAL_2, NOW, NOW_PLUS_10_YEARS));
127             final KeyPair pair2 = mGenerator.generateKeyPair();
128             assertNotNull("The KeyPair returned should not be null", pair2);
129             assertKeyPairCorrect(pair2, TEST_ALIAS_2, TEST_DN_2, TEST_SERIAL_2, NOW,
130                     NOW_PLUS_10_YEARS);
131         }
132     }
133 
assertKeyPairCorrect(KeyPair pair, String alias, X500Principal dn, BigInteger serial, Date start, Date end)134     private void assertKeyPairCorrect(KeyPair pair, String alias, X500Principal dn,
135             BigInteger serial, Date start, Date end) throws Exception {
136         final PublicKey pubKey = pair.getPublic();
137         assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
138 
139         final PrivateKey privKey = pair.getPrivate();
140         assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
141 
142         final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias);
143         assertNotNull("The user certificate should exist for the generated entry", userCertBytes);
144 
145         final CertificateFactory cf = CertificateFactory.getInstance("X.509");
146         final Certificate userCert = cf
147                 .generateCertificate(new ByteArrayInputStream(userCertBytes));
148 
149         assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate);
150 
151         final X509Certificate x509userCert = (X509Certificate) userCert;
152 
153         assertEquals("PublicKey used to sign certificate should match one returned in KeyPair",
154                 pubKey, x509userCert.getPublicKey());
155 
156         assertEquals("The Subject DN should be the one passed into the params", dn,
157                 x509userCert.getSubjectDN());
158 
159         assertEquals("The Issuer DN should be the same as the Subject DN", dn,
160                 x509userCert.getIssuerDN());
161 
162         assertEquals("The Serial should be the one passed into the params", serial,
163                 x509userCert.getSerialNumber());
164 
165         assertEquals("The notBefore date should be the one passed into the params", start,
166                 x509userCert.getNotBefore());
167 
168         assertEquals("The notAfter date should be the one passed into the params", end,
169                 x509userCert.getNotAfter());
170 
171         x509userCert.verify(pubKey);
172 
173         final byte[] caCerts = mAndroidKeyStore.get(Credentials.CA_CERTIFICATE + alias);
174         assertNull("A list of CA certificates should not exist for the generated entry", caCerts);
175 
176         final byte[] pubKeyBytes = mAndroidKeyStore.getPubkey(Credentials.USER_PRIVATE_KEY + alias);
177         assertNotNull("The keystore should return the public key for the generated key",
178                 pubKeyBytes);
179     }
180 }
181