KeyStoreTest.java revision a920f25fe55fc9afc7640902a200f19ce278588b
1/*
2 * Copyright (C) 2009 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
17package android.security;
18
19import android.app.Activity;
20import android.os.Process;
21import android.security.KeyStore;
22import android.test.ActivityUnitTestCase;
23import android.test.AssertionFailedError;
24import android.test.suitebuilder.annotation.MediumTest;
25import java.nio.charset.StandardCharsets;
26import java.util.Arrays;
27import java.util.Date;
28import java.util.HashSet;
29
30/**
31 * Junit / Instrumentation test case for KeyStore class
32 *
33 * Running the test suite:
34 *
35 *  runtest keystore-unit
36 *
37 * Or this individual test case:
38 *
39 *  runtest --path frameworks/base/keystore/tests/src/android/security/KeyStoreTest.java
40 */
41@MediumTest
42public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
43    private static final String TEST_PASSWD = "12345678";
44    private static final String TEST_PASSWD2 = "87654321";
45    private static final String TEST_KEYNAME = "test-key";
46    private static final String TEST_KEYNAME1 = "test-key.1";
47    private static final String TEST_KEYNAME2 = "test-key\02";
48    private static final byte[] TEST_KEYVALUE = "test value".getBytes(StandardCharsets.UTF_8);
49
50    // "Hello, World" in Chinese
51    private static final String TEST_I18N_KEY = "\u4F60\u597D, \u4E16\u754C";
52    private static final byte[] TEST_I18N_VALUE = TEST_I18N_KEY.getBytes(StandardCharsets.UTF_8);
53
54    // Test vector data for signatures
55    private static final byte[] TEST_DATA =  new byte[256];
56    static {
57        for (int i = 0; i < TEST_DATA.length; i++) {
58            TEST_DATA[i] = (byte) i;
59        }
60    }
61
62    private KeyStore mKeyStore = null;
63
64    public KeyStoreTest() {
65        super(Activity.class);
66    }
67
68    private static final byte[] PRIVKEY_BYTES = hexToBytes(
69            "308204BE020100300D06092A864886F70D0101010500048204A8308204A4020100028201" +
70            "0100E0473E8AB8F2284FEB9E742FF9748FA118ED98633C92F52AEB7A2EBE0D3BE60329BE" +
71            "766AD10EB6A515D0D2CFD9BEA7930F0C306537899F7958CD3E85B01F8818524D312584A9" +
72            "4B251E3625B54141EDBFEE198808E1BB97FC7CB49B9EAAAF68E9C98D7D0EDC53BBC0FA00" +
73            "34356D6305FBBCC3C7001405386ABBC873CB0F3EF7425F3D33DF7B315AE036D2A0B66AFD" +
74            "47503B169BF36E3B5162515B715FDA83DEAF2C58AEB9ABFB3097C3CC9DD9DBE5EF296C17" +
75            "6139028E8A671E63056D45F40188D2C4133490845DE52C2534E9C6B2478C07BDAE928823" +
76            "B62D066C7770F9F63F3DBA247F530844747BE7AAA85D853B8BD244ACEC3DE3C89AB46453" +
77            "AB4D24C3AC6902030100010282010037784776A5F17698F5AC960DFB83A1B67564E648BD" +
78            "0597CF8AB8087186F2669C27A9ECBDD480F0197A80D07309E6C6A96F925331E57F8B4AC6" +
79            "F4D45EDA45A23269C09FC428C07A4E6EDF738A15DEC97FABD2F2BB47A14F20EA72FCFE4C" +
80            "36E01ADA77BD137CD8D4DA10BB162E94A4662971F175F985FA188F056CB97EE2816F43AB" +
81            "9D3747612486CDA8C16196C30818A995EC85D38467791267B3BF21F273710A6925862576" +
82            "841C5B6712C12D4BD20A2F3299ADB7C135DA5E9515ABDA76E7CAF2A3BE80551D073B78BF" +
83            "1162C48AD2B7F4743A0238EE4D252F7D5E7E6533CCAE64CCB39360075A2FD1E034EC3AE5" +
84            "CE9C408CCBF0E25E4114021687B3DD4754AE8102818100F541884BC3737B2922D4119EF4" +
85            "5E2DEE2CD4CBB75F45505A157AA5009F99C73A2DF0724AC46024306332EA898177634546" +
86            "5DC6DF1E0A6F140AFF3B7396E6A8994AC5DAA96873472FE37749D14EB3E075E629DBEB35" +
87            "83338A6F3649D0A2654A7A42FD9AB6BFA4AC4D481D390BB229B064BDC311CC1BE1B63189" +
88            "DA7C40CDECF2B102818100EA1A742DDB881CEDB7288C87E38D868DD7A409D15A43F445D5" +
89            "377A0B5731DDBFCA2DAF28A8E13CD5C0AFCEC3347D74A39E235A3CD9633F274DE2B94F92" +
90            "DF43833911D9E9F1CF58F27DE2E08FF45964C720D3EC2139DC7CAFC912953CDECB2F355A" +
91            "2E2C35A50FAD754CB3B23166424BA3B6E3112A2B898C38C5C15EDB238693390281805182" +
92            "8F1EC6FD996029901BAF1D7E337BA5F0AF27E984EAD895ACE62BD7DF4EE45A224089F2CC" +
93            "151AF3CD173FCE0474BCB04F386A2CDCC0E0036BA2419F54579262D47100BE931984A3EF" +
94            "A05BECF141574DC079B3A95C4A83E6C43F3214D6DF32D512DE198085E531E616B83FD7DD" +
95            "9D1F4E2607C3333D07C55D107D1D3893587102818100DB4FB50F50DE8EDB53FF34C80931" +
96            "88A0512867DA2CCA04897759E587C244010DAF8664D59E8083D16C164789301F67A9F078" +
97            "060D834A2ADBD367575B68A8A842C2B02A89B3F31FCCEC8A22FE395795C5C6C7422B4E5D" +
98            "74A1E9A8F30E7759B9FC2D639C1F15673E84E93A5EF1506F4315383C38D45CBD1B14048F" +
99            "4721DC82326102818100D8114593AF415FB612DBF1923710D54D07486205A76A3B431949" +
100            "68C0DFF1F11EF0F61A4A337D5FD3741BBC9640E447B8B6B6C47C3AC1204357D3B0C55BA9" +
101            "286BDA73F629296F5FA9146D8976357D3C751E75148696A40B74685C82CE30902D639D72" +
102            "4FF24D5E2E9407EE34EDED2E3B4DF65AA9BCFEB6DF28D07BA6903F165768");
103
104
105    private static byte[] hexToBytes(String s) {
106        int len = s.length();
107        byte[] data = new byte[len / 2];
108        for (int i = 0; i < len; i += 2) {
109            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(
110                    s.charAt(i + 1), 16));
111        }
112        return data;
113    }
114
115    @Override
116    protected void setUp() throws Exception {
117        mKeyStore = KeyStore.getInstance();
118        if (mKeyStore.state() != KeyStore.State.UNINITIALIZED) {
119            mKeyStore.reset();
120        }
121        assertEquals("KeyStore should be in an uninitialized state",
122                KeyStore.State.UNINITIALIZED, mKeyStore.state());
123        super.setUp();
124    }
125
126    @Override
127    protected void tearDown() throws Exception {
128        mKeyStore.reset();
129        super.tearDown();
130    }
131
132    public void testState() throws Exception {
133        assertEquals(KeyStore.State.UNINITIALIZED, mKeyStore.state());
134    }
135
136    public void testPassword() throws Exception {
137        assertTrue(mKeyStore.password(TEST_PASSWD));
138        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
139    }
140
141    public void testGet() throws Exception {
142        assertNull(mKeyStore.get(TEST_KEYNAME));
143        mKeyStore.password(TEST_PASSWD);
144        assertNull(mKeyStore.get(TEST_KEYNAME));
145        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
146                KeyStore.FLAG_ENCRYPTED));
147        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
148    }
149
150    public void testPut() throws Exception {
151        assertNull(mKeyStore.get(TEST_KEYNAME));
152        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
153                KeyStore.FLAG_ENCRYPTED));
154        assertFalse(mKeyStore.contains(TEST_KEYNAME));
155        mKeyStore.password(TEST_PASSWD);
156        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
157                KeyStore.FLAG_ENCRYPTED));
158        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
159    }
160
161    public void testPut_grantedUid_Wifi() throws Exception {
162        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
163        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
164                KeyStore.FLAG_ENCRYPTED));
165        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
166        mKeyStore.password(TEST_PASSWD);
167        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
168                KeyStore.FLAG_ENCRYPTED));
169        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
170    }
171
172    public void testPut_ungrantedUid_Bluetooth() throws Exception {
173        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
174        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
175                KeyStore.FLAG_ENCRYPTED));
176        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
177        mKeyStore.password(TEST_PASSWD);
178        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
179                KeyStore.FLAG_ENCRYPTED));
180        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
181    }
182
183    public void testI18n() throws Exception {
184        assertFalse(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
185                KeyStore.FLAG_ENCRYPTED));
186        assertFalse(mKeyStore.contains(TEST_I18N_KEY));
187        mKeyStore.password(TEST_I18N_KEY);
188        assertTrue(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
189                KeyStore.FLAG_ENCRYPTED));
190        assertTrue(mKeyStore.contains(TEST_I18N_KEY));
191    }
192
193    public void testDelete() throws Exception {
194        assertFalse(mKeyStore.delete(TEST_KEYNAME));
195        mKeyStore.password(TEST_PASSWD);
196        assertFalse(mKeyStore.delete(TEST_KEYNAME));
197
198        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
199                KeyStore.FLAG_ENCRYPTED));
200        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
201        assertTrue(mKeyStore.delete(TEST_KEYNAME));
202        assertNull(mKeyStore.get(TEST_KEYNAME));
203    }
204
205    public void testDelete_grantedUid_Wifi() throws Exception {
206        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
207        mKeyStore.password(TEST_PASSWD);
208        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
209
210        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
211                KeyStore.FLAG_ENCRYPTED));
212        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
213        assertTrue(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
214        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
215    }
216
217    public void testDelete_ungrantedUid_Bluetooth() throws Exception {
218        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
219        mKeyStore.password(TEST_PASSWD);
220        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
221
222        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
223                KeyStore.FLAG_ENCRYPTED));
224        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
225        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
226        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
227    }
228
229    public void testContains() throws Exception {
230        assertFalse(mKeyStore.contains(TEST_KEYNAME));
231
232        assertTrue(mKeyStore.password(TEST_PASSWD));
233        assertFalse(mKeyStore.contains(TEST_KEYNAME));
234
235        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
236                KeyStore.FLAG_ENCRYPTED));
237        assertTrue(mKeyStore.contains(TEST_KEYNAME));
238    }
239
240    public void testContains_grantedUid_Wifi() throws Exception {
241        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
242
243        assertTrue(mKeyStore.password(TEST_PASSWD));
244        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
245
246        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
247                KeyStore.FLAG_ENCRYPTED));
248        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
249    }
250
251    public void testContains_grantedUid_Bluetooth() throws Exception {
252        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
253
254        assertTrue(mKeyStore.password(TEST_PASSWD));
255        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
256
257        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
258                KeyStore.FLAG_ENCRYPTED));
259        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
260    }
261
262    public void testSaw() throws Exception {
263        String[] emptyResult = mKeyStore.saw(TEST_KEYNAME);
264        assertNotNull(emptyResult);
265        assertEquals(0, emptyResult.length);
266
267        mKeyStore.password(TEST_PASSWD);
268        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
269        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
270
271        String[] results = mKeyStore.saw(TEST_KEYNAME);
272        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
273                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
274                     new HashSet(Arrays.asList(results)));
275    }
276
277    public void testSaw_ungrantedUid_Bluetooth() throws Exception {
278        String[] results1 = mKeyStore.saw(TEST_KEYNAME, Process.BLUETOOTH_UID);
279        assertNull(results1);
280
281        mKeyStore.password(TEST_PASSWD);
282        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
283        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
284
285        String[] results2 = mKeyStore.saw(TEST_KEYNAME, Process.BLUETOOTH_UID);
286        assertNull(results2);
287    }
288
289    public void testSaw_grantedUid_Wifi() throws Exception {
290        String[] results1 = mKeyStore.saw(TEST_KEYNAME, Process.WIFI_UID);
291        assertNotNull(results1);
292        assertEquals(0, results1.length);
293
294        mKeyStore.password(TEST_PASSWD);
295        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
296        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
297
298        String[] results2 = mKeyStore.saw(TEST_KEYNAME, Process.WIFI_UID);
299        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
300                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
301                     new HashSet(Arrays.asList(results2)));
302    }
303
304    public void testSaw_grantedUid_Vpn() throws Exception {
305        String[] results1 = mKeyStore.saw(TEST_KEYNAME, Process.VPN_UID);
306        assertNotNull(results1);
307        assertEquals(0, results1.length);
308
309        mKeyStore.password(TEST_PASSWD);
310        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
311        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
312
313        String[] results2 = mKeyStore.saw(TEST_KEYNAME, Process.VPN_UID);
314        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
315                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
316                     new HashSet(Arrays.asList(results2)));
317    }
318
319    public void testLock() throws Exception {
320        assertFalse(mKeyStore.lock());
321
322        mKeyStore.password(TEST_PASSWD);
323        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
324
325        assertTrue(mKeyStore.lock());
326        assertEquals(KeyStore.State.LOCKED, mKeyStore.state());
327    }
328
329    public void testUnlock() throws Exception {
330        mKeyStore.password(TEST_PASSWD);
331        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
332        mKeyStore.lock();
333
334        assertFalse(mKeyStore.unlock(TEST_PASSWD2));
335        assertTrue(mKeyStore.unlock(TEST_PASSWD));
336    }
337
338    public void testIsEmpty() throws Exception {
339        assertTrue(mKeyStore.isEmpty());
340        mKeyStore.password(TEST_PASSWD);
341        assertTrue(mKeyStore.isEmpty());
342        mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
343        assertFalse(mKeyStore.isEmpty());
344        mKeyStore.reset();
345        assertTrue(mKeyStore.isEmpty());
346    }
347
348    public void testGenerate_NotInitialized_Fail() throws Exception {
349        assertFalse("Should fail when keystore is not initialized",
350                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
351    }
352
353    public void testGenerate_Locked_Fail() throws Exception {
354        mKeyStore.password(TEST_PASSWD);
355        mKeyStore.lock();
356        assertFalse("Should fail when keystore is locked",
357                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
358    }
359
360    public void testGenerate_Success() throws Exception {
361        assertTrue(mKeyStore.password(TEST_PASSWD));
362
363        assertTrue("Should be able to generate key when unlocked",
364                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
365        assertTrue(mKeyStore.contains(TEST_KEYNAME));
366        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
367    }
368
369    public void testGenerate_grantedUid_Wifi_Success() throws Exception {
370        assertTrue(mKeyStore.password(TEST_PASSWD));
371
372        assertTrue("Should be able to generate key when unlocked",
373                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED));
374        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
375        assertFalse(mKeyStore.contains(TEST_KEYNAME));
376    }
377
378    public void testGenerate_ungrantedUid_Bluetooth_Failure() throws Exception {
379        assertTrue(mKeyStore.password(TEST_PASSWD));
380
381        assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID, KeyStore.FLAG_ENCRYPTED));
382        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
383        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
384        assertFalse(mKeyStore.contains(TEST_KEYNAME));
385    }
386
387    public void testImport_Success() throws Exception {
388        assertTrue(mKeyStore.password(TEST_PASSWD));
389
390        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
391                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
392        assertTrue(mKeyStore.contains(TEST_KEYNAME));
393        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
394    }
395
396    public void testImport_grantedUid_Wifi_Success() throws Exception {
397        assertTrue(mKeyStore.password(TEST_PASSWD));
398
399        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
400                PRIVKEY_BYTES, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED));
401        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
402        assertFalse(mKeyStore.contains(TEST_KEYNAME));
403    }
404
405    public void testImport_ungrantedUid_Bluetooth_Failure() throws Exception {
406        assertTrue(mKeyStore.password(TEST_PASSWD));
407
408        assertFalse(mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES, Process.BLUETOOTH_UID,
409                KeyStore.FLAG_ENCRYPTED));
410        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
411        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
412        assertFalse(mKeyStore.contains(TEST_KEYNAME));
413    }
414
415    public void testImport_Failure_BadEncoding() throws Exception {
416        mKeyStore.password(TEST_PASSWD);
417
418        assertFalse("Invalid DER-encoded key should not be imported", mKeyStore.importKey(
419                TEST_KEYNAME, TEST_DATA, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
420        assertFalse(mKeyStore.contains(TEST_KEYNAME));
421        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
422    }
423
424    public void testSign_Success() throws Exception {
425        mKeyStore.password(TEST_PASSWD);
426
427        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
428        assertTrue(mKeyStore.contains(TEST_KEYNAME));
429        final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
430
431        assertNotNull("Signature should not be null", signature);
432    }
433
434    public void testVerify_Success() throws Exception {
435        mKeyStore.password(TEST_PASSWD);
436
437        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
438        assertTrue(mKeyStore.contains(TEST_KEYNAME));
439        final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
440
441        assertNotNull("Signature should not be null", signature);
442
443        assertTrue("Signature should verify with same data",
444                mKeyStore.verify(TEST_KEYNAME, TEST_DATA, signature));
445    }
446
447    public void testSign_NotInitialized_Failure() throws Exception {
448        assertNull("Should not be able to sign without first initializing the keystore",
449                mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
450    }
451
452    public void testSign_NotGenerated_Failure() throws Exception {
453        mKeyStore.password(TEST_PASSWD);
454
455        assertNull("Should not be able to sign without first generating keys",
456                mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
457    }
458
459    public void testGrant_Generated_Success() throws Exception {
460        assertTrue("Password should work for keystore",
461                mKeyStore.password(TEST_PASSWD));
462
463        assertTrue("Should be able to generate key for testcase",
464                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
465
466        assertTrue("Should be able to grant key to other user",
467                mKeyStore.grant(TEST_KEYNAME, 0));
468    }
469
470    public void testGrant_Imported_Success() throws Exception {
471        assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD));
472
473        assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
474                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
475
476        assertTrue("Should be able to grant key to other user", mKeyStore.grant(TEST_KEYNAME, 0));
477    }
478
479    public void testGrant_NoKey_Failure() throws Exception {
480        assertTrue("Should be able to unlock keystore for test",
481                mKeyStore.password(TEST_PASSWD));
482
483        assertFalse("Should not be able to grant without first initializing the keystore",
484                mKeyStore.grant(TEST_KEYNAME, 0));
485    }
486
487    public void testGrant_NotInitialized_Failure() throws Exception {
488        assertFalse("Should not be able to grant without first initializing the keystore",
489                mKeyStore.grant(TEST_KEYNAME, 0));
490    }
491
492    public void testUngrant_Generated_Success() throws Exception {
493        assertTrue("Password should work for keystore",
494                mKeyStore.password(TEST_PASSWD));
495
496        assertTrue("Should be able to generate key for testcase",
497                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
498
499        assertTrue("Should be able to grant key to other user",
500                mKeyStore.grant(TEST_KEYNAME, 0));
501
502        assertTrue("Should be able to ungrant key to other user",
503                mKeyStore.ungrant(TEST_KEYNAME, 0));
504    }
505
506    public void testUngrant_Imported_Success() throws Exception {
507        assertTrue("Password should work for keystore",
508                mKeyStore.password(TEST_PASSWD));
509
510        assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
511                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
512
513        assertTrue("Should be able to grant key to other user",
514                mKeyStore.grant(TEST_KEYNAME, 0));
515
516        assertTrue("Should be able to ungrant key to other user",
517                mKeyStore.ungrant(TEST_KEYNAME, 0));
518    }
519
520    public void testUngrant_NotInitialized_Failure() throws Exception {
521        assertFalse("Should fail to ungrant key when keystore not initialized",
522                mKeyStore.ungrant(TEST_KEYNAME, 0));
523    }
524
525    public void testUngrant_NoGrant_Failure() throws Exception {
526        assertTrue("Password should work for keystore",
527                mKeyStore.password(TEST_PASSWD));
528
529        assertTrue("Should be able to generate key for testcase",
530                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
531
532        assertFalse("Should not be able to revoke not existent grant",
533                mKeyStore.ungrant(TEST_KEYNAME, 0));
534    }
535
536    public void testUngrant_DoubleUngrant_Failure() throws Exception {
537        assertTrue("Password should work for keystore",
538                mKeyStore.password(TEST_PASSWD));
539
540        assertTrue("Should be able to generate key for testcase",
541                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
542
543        assertTrue("Should be able to grant key to other user",
544                mKeyStore.grant(TEST_KEYNAME, 0));
545
546        assertTrue("Should be able to ungrant key to other user",
547                mKeyStore.ungrant(TEST_KEYNAME, 0));
548
549        assertFalse("Should fail to ungrant key to other user second time",
550                mKeyStore.ungrant(TEST_KEYNAME, 0));
551    }
552
553    public void testUngrant_DoubleGrantUngrant_Failure() throws Exception {
554        assertTrue("Password should work for keystore",
555                mKeyStore.password(TEST_PASSWD));
556
557        assertTrue("Should be able to generate key for testcase",
558                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
559
560        assertTrue("Should be able to grant key to other user",
561                mKeyStore.grant(TEST_KEYNAME, 0));
562
563        assertTrue("Should be able to grant key to other user a second time",
564                mKeyStore.grant(TEST_KEYNAME, 0));
565
566        assertTrue("Should be able to ungrant key to other user",
567                mKeyStore.ungrant(TEST_KEYNAME, 0));
568
569        assertFalse("Should fail to ungrant key to other user second time",
570                mKeyStore.ungrant(TEST_KEYNAME, 0));
571    }
572
573    public void testDuplicate_grantedUid_Wifi_Success() throws Exception {
574        assertTrue(mKeyStore.password(TEST_PASSWD));
575
576        assertFalse(mKeyStore.contains(TEST_KEYNAME));
577
578        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
579
580        assertTrue(mKeyStore.contains(TEST_KEYNAME));
581        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
582
583        // source doesn't exist
584        assertFalse(mKeyStore.duplicate(TEST_KEYNAME1, -1, TEST_KEYNAME1, Process.WIFI_UID));
585        assertFalse(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
586
587        // Copy from current UID to granted UID
588        assertTrue(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME1, Process.WIFI_UID));
589        assertTrue(mKeyStore.contains(TEST_KEYNAME));
590        assertFalse(mKeyStore.contains(TEST_KEYNAME1));
591        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
592        assertTrue(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
593        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME1, Process.WIFI_UID));
594
595        // Copy from granted UID to same granted UID
596        assertTrue(mKeyStore.duplicate(TEST_KEYNAME1, Process.WIFI_UID, TEST_KEYNAME2,
597                Process.WIFI_UID));
598        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
599        assertTrue(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
600        assertTrue(mKeyStore.contains(TEST_KEYNAME2, Process.WIFI_UID));
601        assertFalse(mKeyStore.duplicate(TEST_KEYNAME1, Process.WIFI_UID, TEST_KEYNAME2,
602                Process.WIFI_UID));
603
604        assertTrue(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, -1));
605        assertTrue(mKeyStore.contains(TEST_KEYNAME));
606        assertFalse(mKeyStore.contains(TEST_KEYNAME1));
607        assertTrue(mKeyStore.contains(TEST_KEYNAME2));
608        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, -1));
609    }
610
611    public void testDuplicate_ungrantedUid_Bluetooth_Failure() throws Exception {
612        assertTrue(mKeyStore.password(TEST_PASSWD));
613
614        assertFalse(mKeyStore.contains(TEST_KEYNAME));
615
616        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
617
618        assertTrue(mKeyStore.contains(TEST_KEYNAME));
619        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
620
621        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, Process.BLUETOOTH_UID));
622        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, Process.BLUETOOTH_UID, TEST_KEYNAME2,
623                Process.BLUETOOTH_UID));
624
625        assertTrue(mKeyStore.contains(TEST_KEYNAME));
626        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
627    }
628
629    /**
630     * The amount of time to allow before and after expected time for variance
631     * in timing tests.
632     */
633    private static final long SLOP_TIME_MILLIS = 15000L;
634
635    public void testGetmtime_Success() throws Exception {
636        assertTrue("Password should work for keystore",
637                mKeyStore.password(TEST_PASSWD));
638
639        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
640                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
641
642        long now = System.currentTimeMillis();
643        long actual = mKeyStore.getmtime(TEST_KEYNAME);
644
645        long expectedAfter = now - SLOP_TIME_MILLIS;
646        long expectedBefore = now + SLOP_TIME_MILLIS;
647
648        assertLessThan("Time should be close to current time", expectedBefore, actual);
649        assertGreaterThan("Time should be close to current time", expectedAfter, actual);
650    }
651
652    private static void assertLessThan(String explanation, long expectedBefore, long actual) {
653        if (actual >= expectedBefore) {
654            throw new AssertionFailedError(explanation + ": actual=" + actual
655                    + ", expected before: " + expectedBefore);
656        }
657    }
658
659    private static void assertGreaterThan(String explanation, long expectedAfter, long actual) {
660        if (actual <= expectedAfter) {
661            throw new AssertionFailedError(explanation + ": actual=" + actual
662                    + ", expected after: " + expectedAfter);
663        }
664    }
665
666    public void testGetmtime_NonExist_Failure() throws Exception {
667        assertTrue("Password should work for keystore",
668                mKeyStore.password(TEST_PASSWD));
669
670        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
671                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
672
673        assertEquals("-1 should be returned for non-existent key",
674                -1L, mKeyStore.getmtime(TEST_KEYNAME2));
675    }
676}
677