Home | History | Annotate | Download | only in security
      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 
     17 package android.security.tests;
     18 
     19 import android.app.Activity;
     20 import android.security.KeyStore;
     21 import android.test.ActivityUnitTestCase;
     22 import android.test.suitebuilder.annotation.MediumTest;
     23 import java.nio.charset.Charsets;
     24 import java.util.Arrays;
     25 import java.util.HashSet;
     26 
     27 /**
     28  * Junit / Instrumentation test case for KeyStore class
     29  *
     30  * Running the test suite:
     31  *
     32  *  adb shell am instrument -w android.security.tests/.KeyStoreTestRunner
     33  */
     34 @MediumTest
     35 public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
     36     private static final String TEST_PASSWD = "12345678";
     37     private static final String TEST_PASSWD2 = "87654321";
     38     private static final String TEST_KEYNAME = "testkey";
     39     private static final String TEST_KEYNAME1 = "testkey1";
     40     private static final String TEST_KEYNAME2 = "testkey2";
     41     private static final byte[] TEST_KEYVALUE = "test value".getBytes(Charsets.UTF_8);
     42 
     43     // "Hello, World" in Chinese
     44     private static final String TEST_I18N_KEY = "\u4F60\u597D, \u4E16\u754C";
     45     private static final byte[] TEST_I18N_VALUE = TEST_I18N_KEY.getBytes(Charsets.UTF_8);
     46 
     47     // Test vector data for signatures
     48     private static final byte[] TEST_DATA = {
     49             (byte) 0x00, (byte) 0xA0, (byte) 0xFF, (byte) 0x0A, (byte) 0x00, (byte) 0xFF,
     50             (byte) 0xAA, (byte) 0x55, (byte) 0x05, (byte) 0x5A,
     51     };
     52 
     53     private KeyStore mKeyStore = null;
     54 
     55     public KeyStoreTest() {
     56         super(Activity.class);
     57     }
     58 
     59     private static final byte[] PRIVKEY_BYTES = hexToBytes(
     60             "308204BE020100300D06092A864886F70D0101010500048204A8308204A4020100028201" +
     61             "0100E0473E8AB8F2284FEB9E742FF9748FA118ED98633C92F52AEB7A2EBE0D3BE60329BE" +
     62             "766AD10EB6A515D0D2CFD9BEA7930F0C306537899F7958CD3E85B01F8818524D312584A9" +
     63             "4B251E3625B54141EDBFEE198808E1BB97FC7CB49B9EAAAF68E9C98D7D0EDC53BBC0FA00" +
     64             "34356D6305FBBCC3C7001405386ABBC873CB0F3EF7425F3D33DF7B315AE036D2A0B66AFD" +
     65             "47503B169BF36E3B5162515B715FDA83DEAF2C58AEB9ABFB3097C3CC9DD9DBE5EF296C17" +
     66             "6139028E8A671E63056D45F40188D2C4133490845DE52C2534E9C6B2478C07BDAE928823" +
     67             "B62D066C7770F9F63F3DBA247F530844747BE7AAA85D853B8BD244ACEC3DE3C89AB46453" +
     68             "AB4D24C3AC6902030100010282010037784776A5F17698F5AC960DFB83A1B67564E648BD" +
     69             "0597CF8AB8087186F2669C27A9ECBDD480F0197A80D07309E6C6A96F925331E57F8B4AC6" +
     70             "F4D45EDA45A23269C09FC428C07A4E6EDF738A15DEC97FABD2F2BB47A14F20EA72FCFE4C" +
     71             "36E01ADA77BD137CD8D4DA10BB162E94A4662971F175F985FA188F056CB97EE2816F43AB" +
     72             "9D3747612486CDA8C16196C30818A995EC85D38467791267B3BF21F273710A6925862576" +
     73             "841C5B6712C12D4BD20A2F3299ADB7C135DA5E9515ABDA76E7CAF2A3BE80551D073B78BF" +
     74             "1162C48AD2B7F4743A0238EE4D252F7D5E7E6533CCAE64CCB39360075A2FD1E034EC3AE5" +
     75             "CE9C408CCBF0E25E4114021687B3DD4754AE8102818100F541884BC3737B2922D4119EF4" +
     76             "5E2DEE2CD4CBB75F45505A157AA5009F99C73A2DF0724AC46024306332EA898177634546" +
     77             "5DC6DF1E0A6F140AFF3B7396E6A8994AC5DAA96873472FE37749D14EB3E075E629DBEB35" +
     78             "83338A6F3649D0A2654A7A42FD9AB6BFA4AC4D481D390BB229B064BDC311CC1BE1B63189" +
     79             "DA7C40CDECF2B102818100EA1A742DDB881CEDB7288C87E38D868DD7A409D15A43F445D5" +
     80             "377A0B5731DDBFCA2DAF28A8E13CD5C0AFCEC3347D74A39E235A3CD9633F274DE2B94F92" +
     81             "DF43833911D9E9F1CF58F27DE2E08FF45964C720D3EC2139DC7CAFC912953CDECB2F355A" +
     82             "2E2C35A50FAD754CB3B23166424BA3B6E3112A2B898C38C5C15EDB238693390281805182" +
     83             "8F1EC6FD996029901BAF1D7E337BA5F0AF27E984EAD895ACE62BD7DF4EE45A224089F2CC" +
     84             "151AF3CD173FCE0474BCB04F386A2CDCC0E0036BA2419F54579262D47100BE931984A3EF" +
     85             "A05BECF141574DC079B3A95C4A83E6C43F3214D6DF32D512DE198085E531E616B83FD7DD" +
     86             "9D1F4E2607C3333D07C55D107D1D3893587102818100DB4FB50F50DE8EDB53FF34C80931" +
     87             "88A0512867DA2CCA04897759E587C244010DAF8664D59E8083D16C164789301F67A9F078" +
     88             "060D834A2ADBD367575B68A8A842C2B02A89B3F31FCCEC8A22FE395795C5C6C7422B4E5D" +
     89             "74A1E9A8F30E7759B9FC2D639C1F15673E84E93A5EF1506F4315383C38D45CBD1B14048F" +
     90             "4721DC82326102818100D8114593AF415FB612DBF1923710D54D07486205A76A3B431949" +
     91             "68C0DFF1F11EF0F61A4A337D5FD3741BBC9640E447B8B6B6C47C3AC1204357D3B0C55BA9" +
     92             "286BDA73F629296F5FA9146D8976357D3C751E75148696A40B74685C82CE30902D639D72" +
     93             "4FF24D5E2E9407EE34EDED2E3B4DF65AA9BCFEB6DF28D07BA6903F165768");
     94 
     95 
     96     private static byte[] hexToBytes(String s) {
     97         int len = s.length();
     98         byte[] data = new byte[len / 2];
     99         for (int i = 0; i < len; i += 2) {
    100             data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(
    101                     s.charAt(i + 1), 16));
    102         }
    103         return data;
    104     }
    105 
    106     @Override
    107     protected void setUp() throws Exception {
    108         mKeyStore = KeyStore.getInstance();
    109         if (mKeyStore.state() != KeyStore.State.UNINITIALIZED) {
    110             mKeyStore.reset();
    111         }
    112         assertEquals("KeyStore should be in an uninitialized state",
    113                 KeyStore.State.UNINITIALIZED, mKeyStore.state());
    114         super.setUp();
    115     }
    116 
    117     @Override
    118     protected void tearDown() throws Exception {
    119         mKeyStore.reset();
    120         super.tearDown();
    121     }
    122 
    123     public void teststate() throws Exception {
    124         assertEquals(KeyStore.State.UNINITIALIZED, mKeyStore.state());
    125     }
    126 
    127     public void testPassword() throws Exception {
    128         assertTrue(mKeyStore.password(TEST_PASSWD));
    129         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
    130     }
    131 
    132     public void testGet() throws Exception {
    133         assertNull(mKeyStore.get(TEST_KEYNAME));
    134         mKeyStore.password(TEST_PASSWD);
    135         assertNull(mKeyStore.get(TEST_KEYNAME));
    136         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE));
    137         assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
    138     }
    139 
    140     public void testPut() throws Exception {
    141         assertNull(mKeyStore.get(TEST_KEYNAME));
    142         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE));
    143         assertFalse(mKeyStore.contains(TEST_KEYNAME));
    144         mKeyStore.password(TEST_PASSWD);
    145         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE));
    146         assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
    147     }
    148 
    149     public void testI18n() throws Exception {
    150         assertFalse(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE));
    151         assertFalse(mKeyStore.contains(TEST_I18N_KEY));
    152         mKeyStore.password(TEST_I18N_KEY);
    153         assertTrue(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE));
    154         assertTrue(mKeyStore.contains(TEST_I18N_KEY));
    155     }
    156 
    157     public void testDelete() throws Exception {
    158         assertTrue(mKeyStore.delete(TEST_KEYNAME));
    159         mKeyStore.password(TEST_PASSWD);
    160         assertTrue(mKeyStore.delete(TEST_KEYNAME));
    161 
    162         mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE);
    163         assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
    164         assertTrue(mKeyStore.delete(TEST_KEYNAME));
    165         assertNull(mKeyStore.get(TEST_KEYNAME));
    166     }
    167 
    168     public void testContains() throws Exception {
    169         assertFalse(mKeyStore.contains(TEST_KEYNAME));
    170 
    171         mKeyStore.password(TEST_PASSWD);
    172         assertFalse(mKeyStore.contains(TEST_KEYNAME));
    173 
    174         mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE);
    175         assertTrue(mKeyStore.contains(TEST_KEYNAME));
    176     }
    177 
    178     public void testSaw() throws Exception {
    179         String[] emptyResult = mKeyStore.saw(TEST_KEYNAME);
    180         assertNotNull(emptyResult);
    181         assertEquals(0, emptyResult.length);
    182 
    183         mKeyStore.password(TEST_PASSWD);
    184         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE);
    185         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE);
    186 
    187         String[] results = mKeyStore.saw(TEST_KEYNAME);
    188         assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
    189                                                TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
    190                      new HashSet(Arrays.asList(results)));
    191     }
    192 
    193     public void testLock() throws Exception {
    194         assertFalse(mKeyStore.lock());
    195 
    196         mKeyStore.password(TEST_PASSWD);
    197         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
    198 
    199         assertTrue(mKeyStore.lock());
    200         assertEquals(KeyStore.State.LOCKED, mKeyStore.state());
    201     }
    202 
    203     public void testUnlock() throws Exception {
    204         mKeyStore.password(TEST_PASSWD);
    205         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
    206         mKeyStore.lock();
    207 
    208         assertFalse(mKeyStore.unlock(TEST_PASSWD2));
    209         assertTrue(mKeyStore.unlock(TEST_PASSWD));
    210     }
    211 
    212     public void testIsEmpty() throws Exception {
    213         assertTrue(mKeyStore.isEmpty());
    214         mKeyStore.password(TEST_PASSWD);
    215         assertTrue(mKeyStore.isEmpty());
    216         mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE);
    217         assertFalse(mKeyStore.isEmpty());
    218         mKeyStore.reset();
    219         assertTrue(mKeyStore.isEmpty());
    220     }
    221 
    222     public void testGenerate_NotInitialized_Fail() throws Exception {
    223         assertFalse("Should fail when keystore is not initialized",
    224                 mKeyStore.generate(TEST_KEYNAME));
    225     }
    226 
    227     public void testGenerate_Locked_Fail() throws Exception {
    228         mKeyStore.password(TEST_PASSWD);
    229         mKeyStore.lock();
    230         assertFalse("Should fail when keystore is locked", mKeyStore.generate(TEST_KEYNAME));
    231     }
    232 
    233     public void testGenerate_Success() throws Exception {
    234         mKeyStore.password(TEST_PASSWD);
    235 
    236         assertTrue("Should be able to generate key when unlocked",
    237                 mKeyStore.generate(TEST_KEYNAME));
    238     }
    239 
    240     public void testImport_Success() throws Exception {
    241         mKeyStore.password(TEST_PASSWD);
    242 
    243         assertTrue("Should be able to import key when unlocked",
    244                 mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES));
    245     }
    246 
    247     public void testImport_Failure_BadEncoding() throws Exception {
    248         mKeyStore.password(TEST_PASSWD);
    249 
    250         assertFalse("Invalid DER-encoded key should not be imported",
    251                 mKeyStore.importKey(TEST_KEYNAME, TEST_DATA));
    252     }
    253 
    254     public void testSign_Success() throws Exception {
    255         mKeyStore.password(TEST_PASSWD);
    256 
    257         assertTrue(mKeyStore.generate(TEST_KEYNAME));
    258         final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
    259 
    260         assertNotNull("Signature should not be null", signature);
    261     }
    262 
    263     public void testVerify_Success() throws Exception {
    264         mKeyStore.password(TEST_PASSWD);
    265 
    266         assertTrue(mKeyStore.generate(TEST_KEYNAME));
    267         final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
    268 
    269         assertNotNull("Signature should not be null", signature);
    270 
    271         assertTrue("Signature should verify with same data",
    272                 mKeyStore.verify(TEST_KEYNAME, TEST_DATA, signature));
    273     }
    274 
    275     public void testSign_NotInitialized_Failure() throws Exception {
    276         assertNull("Should not be able to sign without first initializing the keystore",
    277                 mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
    278     }
    279 
    280     public void testSign_NotGenerated_Failure() throws Exception {
    281         mKeyStore.password(TEST_PASSWD);
    282 
    283         assertNull("Should not be able to sign without first generating keys",
    284                 mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
    285     }
    286 
    287     public void testGrant_Generated_Success() throws Exception {
    288         assertTrue("Password should work for keystore",
    289                 mKeyStore.password(TEST_PASSWD));
    290 
    291         assertTrue("Should be able to generate key for testcase",
    292                 mKeyStore.generate(TEST_KEYNAME));
    293 
    294         assertTrue("Should be able to grant key to other user",
    295                 mKeyStore.grant(TEST_KEYNAME, 0));
    296     }
    297 
    298     public void testGrant_Imported_Success() throws Exception {
    299         assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD));
    300 
    301         assertTrue("Should be able to import key for testcase",
    302                 mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES));
    303 
    304         assertTrue("Should be able to grant key to other user", mKeyStore.grant(TEST_KEYNAME, 0));
    305     }
    306 
    307     public void testGrant_NoKey_Failure() throws Exception {
    308         assertTrue("Should be able to unlock keystore for test",
    309                 mKeyStore.password(TEST_PASSWD));
    310 
    311         assertFalse("Should not be able to grant without first initializing the keystore",
    312                 mKeyStore.grant(TEST_KEYNAME, 0));
    313     }
    314 
    315     public void testGrant_NotInitialized_Failure() throws Exception {
    316         assertFalse("Should not be able to grant without first initializing the keystore",
    317                 mKeyStore.grant(TEST_KEYNAME, 0));
    318     }
    319 
    320     public void testUngrant_Generated_Success() throws Exception {
    321         assertTrue("Password should work for keystore",
    322                 mKeyStore.password(TEST_PASSWD));
    323 
    324         assertTrue("Should be able to generate key for testcase",
    325                 mKeyStore.generate(TEST_KEYNAME));
    326 
    327         assertTrue("Should be able to grant key to other user",
    328                 mKeyStore.grant(TEST_KEYNAME, 0));
    329 
    330         assertTrue("Should be able to ungrant key to other user",
    331                 mKeyStore.ungrant(TEST_KEYNAME, 0));
    332     }
    333 
    334     public void testUngrant_Imported_Success() throws Exception {
    335         assertTrue("Password should work for keystore",
    336                 mKeyStore.password(TEST_PASSWD));
    337 
    338         assertTrue("Should be able to import key for testcase",
    339                 mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES));
    340 
    341         assertTrue("Should be able to grant key to other user",
    342                 mKeyStore.grant(TEST_KEYNAME, 0));
    343 
    344         assertTrue("Should be able to ungrant key to other user",
    345                 mKeyStore.ungrant(TEST_KEYNAME, 0));
    346     }
    347 
    348     public void testUngrant_NotInitialized_Failure() throws Exception {
    349         assertFalse("Should fail to ungrant key when keystore not initialized",
    350                 mKeyStore.ungrant(TEST_KEYNAME, 0));
    351     }
    352 
    353     public void testUngrant_NoGrant_Failure() throws Exception {
    354         assertTrue("Password should work for keystore",
    355                 mKeyStore.password(TEST_PASSWD));
    356 
    357         assertTrue("Should be able to generate key for testcase",
    358                 mKeyStore.generate(TEST_KEYNAME));
    359 
    360         assertFalse("Should not be able to revoke not existent grant",
    361                 mKeyStore.ungrant(TEST_KEYNAME, 0));
    362     }
    363 
    364     public void testUngrant_DoubleUngrant_Failure() throws Exception {
    365         assertTrue("Password should work for keystore",
    366                 mKeyStore.password(TEST_PASSWD));
    367 
    368         assertTrue("Should be able to generate key for testcase",
    369                 mKeyStore.generate(TEST_KEYNAME));
    370 
    371         assertTrue("Should be able to grant key to other user",
    372                 mKeyStore.grant(TEST_KEYNAME, 0));
    373 
    374         assertTrue("Should be able to ungrant key to other user",
    375                 mKeyStore.ungrant(TEST_KEYNAME, 0));
    376 
    377         assertFalse("Should fail to ungrant key to other user second time",
    378                 mKeyStore.ungrant(TEST_KEYNAME, 0));
    379     }
    380 
    381     public void testUngrant_DoubleGrantUngrant_Failure() throws Exception {
    382         assertTrue("Password should work for keystore",
    383                 mKeyStore.password(TEST_PASSWD));
    384 
    385         assertTrue("Should be able to generate key for testcase",
    386                 mKeyStore.generate(TEST_KEYNAME));
    387 
    388         assertTrue("Should be able to grant key to other user",
    389                 mKeyStore.grant(TEST_KEYNAME, 0));
    390 
    391         assertTrue("Should be able to grant key to other user a second time",
    392                 mKeyStore.grant(TEST_KEYNAME, 0));
    393 
    394         assertTrue("Should be able to ungrant key to other user",
    395                 mKeyStore.ungrant(TEST_KEYNAME, 0));
    396 
    397         assertFalse("Should fail to ungrant key to other user second time",
    398                 mKeyStore.ungrant(TEST_KEYNAME, 0));
    399     }
    400 }
    401