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