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