1 /* 2 * Copyright (C) 2017 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 com.android.server.locksettings.recoverablekeystore.storage; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertArrayEquals; 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertNull; 24 import static org.junit.Assert.assertTrue; 25 26 import android.content.Context; 27 import android.security.keystore.recovery.RecoveryController; 28 29 import androidx.test.InstrumentationRegistry; 30 import androidx.test.filters.SmallTest; 31 import androidx.test.runner.AndroidJUnit4; 32 33 import com.android.server.locksettings.recoverablekeystore.TestData; 34 import com.android.server.locksettings.recoverablekeystore.WrappedKey; 35 36 import org.junit.After; 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 41 import java.io.File; 42 import java.nio.charset.StandardCharsets; 43 import java.security.KeyPairGenerator; 44 import java.security.PublicKey; 45 import java.security.spec.ECGenParameterSpec; 46 import java.util.List; 47 import java.util.Map; 48 49 @SmallTest 50 @RunWith(AndroidJUnit4.class) 51 public class RecoverableKeyStoreDbTest { 52 private static final String DATABASE_FILE_NAME = "recoverablekeystore.db"; 53 54 private static final String TEST_ROOT_CERT_ALIAS = "trusted_root"; 55 private static final String TEST_ROOT_CERT_ALIAS2 = "another_trusted_root"; 56 57 private RecoverableKeyStoreDb mRecoverableKeyStoreDb; 58 private File mDatabaseFile; 59 60 private static final byte[] SERVER_PARAMS = 61 new byte[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2}; 62 63 private static final byte[] SERVER_PARAMS2 = 64 new byte[]{1, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; 65 66 @Before setUp()67 public void setUp() { 68 Context context = InstrumentationRegistry.getTargetContext(); 69 mDatabaseFile = context.getDatabasePath(DATABASE_FILE_NAME); 70 mRecoverableKeyStoreDb = RecoverableKeyStoreDb.newInstance(context); 71 } 72 73 @After tearDown()74 public void tearDown() { 75 mRecoverableKeyStoreDb.close(); 76 mDatabaseFile.delete(); 77 } 78 79 @Test insertKey_replacesOldKey()80 public void insertKey_replacesOldKey() { 81 int userId = 12; 82 int uid = 10009; 83 String alias = "test-alias"; 84 85 byte[] nonce = getUtf8Bytes("nonce1"); 86 byte[] keyMaterial = getUtf8Bytes("keymaterial1"); 87 byte[] keyMetadata = null; 88 int generationId = 1; 89 WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, keyMetadata, generationId); 90 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey); 91 92 WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 93 assertArrayEquals(nonce, retrievedKey.getNonce()); 94 assertArrayEquals(keyMaterial, retrievedKey.getKeyMaterial()); 95 assertArrayEquals(keyMetadata, retrievedKey.getKeyMetadata()); 96 assertEquals(generationId, retrievedKey.getPlatformKeyGenerationId()); 97 98 nonce = getUtf8Bytes("nonce2"); 99 keyMaterial = getUtf8Bytes("keymaterial2"); 100 keyMetadata = getUtf8Bytes("keymetadata2"); 101 generationId = 2; 102 wrappedKey = new WrappedKey(nonce, keyMaterial, keyMetadata, generationId); 103 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey); 104 105 retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 106 assertArrayEquals(nonce, retrievedKey.getNonce()); 107 assertArrayEquals(keyMaterial, retrievedKey.getKeyMaterial()); 108 assertArrayEquals(keyMetadata, retrievedKey.getKeyMetadata()); 109 assertEquals(generationId, retrievedKey.getPlatformKeyGenerationId()); 110 } 111 112 @Test insertKey_allowsTwoUidsToHaveSameAlias()113 public void insertKey_allowsTwoUidsToHaveSameAlias() { 114 int userId = 6; 115 String alias = "pcoulton"; 116 WrappedKey key1 = new WrappedKey( 117 getUtf8Bytes("nonce1"), 118 getUtf8Bytes("key1"), 119 /*metadata=*/ null, 120 /*platformKeyGenerationId=*/ 1); 121 WrappedKey key2 = new WrappedKey( 122 getUtf8Bytes("nonce2"), 123 getUtf8Bytes("key2"), 124 /*metadata=*/ null, 125 /*platformKeyGenerationId=*/ 1); 126 127 mRecoverableKeyStoreDb.insertKey(userId, /*uid=*/ 1, alias, key1); 128 mRecoverableKeyStoreDb.insertKey(userId, /*uid=*/ 2, alias, key2); 129 130 assertArrayEquals( 131 getUtf8Bytes("nonce1"), 132 mRecoverableKeyStoreDb.getKey(1, alias).getNonce()); 133 assertArrayEquals( 134 getUtf8Bytes("nonce2"), 135 mRecoverableKeyStoreDb.getKey(2, alias).getNonce()); 136 } 137 138 @Test removeKey_removesAKey()139 public void removeKey_removesAKey() { 140 int userId = 6; 141 int uid = 60001; 142 String alias = "rupertbates"; 143 WrappedKey key = new WrappedKey( 144 getUtf8Bytes("nonce1"), 145 getUtf8Bytes("key1"), 146 /*metadata=*/ null, 147 /*platformKeyGenerationId=*/ 1); 148 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, key); 149 150 assertTrue(mRecoverableKeyStoreDb.removeKey(uid, alias)); 151 152 assertNull(mRecoverableKeyStoreDb.getKey(uid, alias)); 153 } 154 155 @Test getKey_returnsNullIfNoKey()156 public void getKey_returnsNullIfNoKey() { 157 WrappedKey key = mRecoverableKeyStoreDb.getKey( 158 /*userId=*/ 1, /*alias=*/ "hello"); 159 160 assertNull(key); 161 } 162 163 @Test getKey_returnsInsertedKey()164 public void getKey_returnsInsertedKey() { 165 int userId = 12; 166 int uid = 1009; 167 int generationId = 6; 168 int status = 120; 169 String alias = "test"; 170 byte[] nonce = getUtf8Bytes("nonce"); 171 byte[] keyMaterial = getUtf8Bytes("keymaterial"); 172 byte[] keyMetadata = getUtf8Bytes("keymetametametadata"); 173 174 WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, keyMetadata, generationId, 120); 175 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey); 176 177 WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 178 179 assertArrayEquals(nonce, retrievedKey.getNonce()); 180 assertArrayEquals(keyMaterial, retrievedKey.getKeyMaterial()); 181 assertArrayEquals(keyMetadata, retrievedKey.getKeyMetadata()); 182 assertEquals(generationId, retrievedKey.getPlatformKeyGenerationId()); 183 assertEquals(status,retrievedKey.getRecoveryStatus()); 184 } 185 186 @Test getAllKeys_getsKeysWithUserIdAndGenerationId()187 public void getAllKeys_getsKeysWithUserIdAndGenerationId() { 188 int userId = 12; 189 int uid = 1009; 190 int generationId = 6; 191 192 String alias1 = "alias1"; 193 byte[] nonce1 = getUtf8Bytes("nonce1"); 194 byte[] keyMaterial1 = getUtf8Bytes("keymaterial1"); 195 byte[] keyMetadata1 = getUtf8Bytes("keyallmetadata1"); 196 WrappedKey wrappedKey1 = new WrappedKey(nonce1, keyMaterial1, keyMetadata1, generationId); 197 mRecoverableKeyStoreDb.insertKey(userId, uid, alias1, wrappedKey1); 198 199 String alias2 = "alias2"; 200 byte[] nonce2 = getUtf8Bytes("nonce2"); 201 byte[] keyMaterial2 = getUtf8Bytes("keymaterial2"); 202 byte[] keyMetadata2 = null; 203 WrappedKey wrappedKey2 = new WrappedKey(nonce2, keyMaterial2, keyMetadata2, generationId); 204 mRecoverableKeyStoreDb.insertKey(userId, uid, alias2, wrappedKey2); 205 206 Map<String, WrappedKey> keys = mRecoverableKeyStoreDb.getAllKeys(userId, uid, generationId); 207 assertEquals(2, keys.size()); 208 209 assertTrue(keys.containsKey(alias1)); 210 WrappedKey retrievedKey1 = keys.get(alias1); 211 assertArrayEquals(nonce1, retrievedKey1.getNonce()); 212 assertArrayEquals(keyMaterial1, retrievedKey1.getKeyMaterial()); 213 assertArrayEquals(keyMetadata1, retrievedKey1.getKeyMetadata()); 214 assertEquals(generationId, retrievedKey1.getPlatformKeyGenerationId()); 215 216 assertTrue(keys.containsKey(alias2)); 217 WrappedKey retrievedKey2 = keys.get(alias2); 218 assertArrayEquals(nonce2, retrievedKey2.getNonce()); 219 assertArrayEquals(keyMaterial2, retrievedKey2.getKeyMaterial()); 220 assertArrayEquals(keyMetadata2, retrievedKey2.getKeyMetadata()); 221 assertEquals(generationId, retrievedKey2.getPlatformKeyGenerationId()); 222 } 223 224 @Test getAllKeys_doesNotReturnKeysWithBadGenerationId()225 public void getAllKeys_doesNotReturnKeysWithBadGenerationId() { 226 int userId = 12; 227 int uid = 6000; 228 WrappedKey wrappedKey = new WrappedKey( 229 getUtf8Bytes("nonce"), 230 getUtf8Bytes("keymaterial"), 231 /*metadata=*/ null, 232 /*platformKeyGenerationId=*/ 5); 233 mRecoverableKeyStoreDb.insertKey( 234 userId, uid, /*alias=*/ "test", wrappedKey); 235 236 Map<String, WrappedKey> keys = mRecoverableKeyStoreDb.getAllKeys( 237 userId, uid, /*generationId=*/ 7); 238 239 assertTrue(keys.isEmpty()); 240 } 241 242 @Test getAllKeys_doesNotReturnKeysWithBadUserId()243 public void getAllKeys_doesNotReturnKeysWithBadUserId() { 244 int generationId = 12; 245 int uid = 10009; 246 WrappedKey wrappedKey = new WrappedKey( 247 getUtf8Bytes("nonce"), getUtf8Bytes("keymaterial"), /*metadata=*/ null, 248 generationId); 249 mRecoverableKeyStoreDb.insertKey( 250 /*userId=*/ 1, uid, /*alias=*/ "test", wrappedKey); 251 252 Map<String, WrappedKey> keys = mRecoverableKeyStoreDb.getAllKeys( 253 /*userId=*/ 2, uid, generationId); 254 255 assertTrue(keys.isEmpty()); 256 } 257 258 @Test getPlatformKeyGenerationId_returnsGenerationId()259 public void getPlatformKeyGenerationId_returnsGenerationId() { 260 int userId = 42; 261 int generationId = 24; 262 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, generationId); 263 264 assertEquals(generationId, mRecoverableKeyStoreDb.getPlatformKeyGenerationId(userId)); 265 } 266 267 @Test getPlatformKeyGenerationId_returnsMinusOneIfNoEntry()268 public void getPlatformKeyGenerationId_returnsMinusOneIfNoEntry() { 269 assertEquals(-1, mRecoverableKeyStoreDb.getPlatformKeyGenerationId(42)); 270 } 271 272 @Test setPlatformKeyGenerationId_replacesOldEntry()273 public void setPlatformKeyGenerationId_replacesOldEntry() { 274 int userId = 42; 275 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, 1); 276 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, 2); 277 278 assertEquals(2, mRecoverableKeyStoreDb.getPlatformKeyGenerationId(userId)); 279 } 280 281 @Test getUserSerialNumbers_returnsSerialNumbers()282 public void getUserSerialNumbers_returnsSerialNumbers() { 283 int userId = 42; 284 int userId2 = 44; 285 Long serialNumber = 24L; 286 Long serialNumber2 = 25L; 287 mRecoverableKeyStoreDb.setUserSerialNumber(userId, serialNumber); 288 mRecoverableKeyStoreDb.setUserSerialNumber(userId2, serialNumber2); 289 290 assertEquals(2, mRecoverableKeyStoreDb.getUserSerialNumbers().size()); 291 assertEquals(serialNumber, mRecoverableKeyStoreDb.getUserSerialNumbers().get(userId)); 292 assertEquals(serialNumber2, mRecoverableKeyStoreDb.getUserSerialNumbers().get(userId2)); 293 } 294 295 @Test getUserSerialNumbers_returnsMinusOneIfNoEntry()296 public void getUserSerialNumbers_returnsMinusOneIfNoEntry() { 297 int userId = 42; 298 int generationId = 24; 299 Long serialNumber = -1L; 300 // Don't set serial number 301 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, generationId); 302 303 assertEquals(1, mRecoverableKeyStoreDb.getUserSerialNumbers().size()); 304 assertEquals(serialNumber, mRecoverableKeyStoreDb.getUserSerialNumbers().get(userId)); 305 } 306 307 @Test setUserSerialNumbers_keepsPlatformKeyGenerationId()308 public void setUserSerialNumbers_keepsPlatformKeyGenerationId() { 309 int userId = 42; 310 int generationId = 110; 311 Long serialNumber = 10L; 312 313 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, generationId); 314 mRecoverableKeyStoreDb.setUserSerialNumber(userId, serialNumber); 315 316 assertEquals(generationId, mRecoverableKeyStoreDb.getPlatformKeyGenerationId(userId)); 317 } 318 319 @Test setPlatformKeyGenerationId_keepsUserSerialNumber()320 public void setPlatformKeyGenerationId_keepsUserSerialNumber() { 321 int userId = 42; 322 int generationId = 110; 323 Long serialNumber = 10L; 324 325 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, generationId); 326 mRecoverableKeyStoreDb.setUserSerialNumber(userId, serialNumber); 327 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, generationId + 1); 328 329 assertEquals(serialNumber, mRecoverableKeyStoreDb.getUserSerialNumbers().get(userId)); 330 } 331 332 @Test setPlatformKeyGenerationId_invalidatesExistingKeysForUser()333 public void setPlatformKeyGenerationId_invalidatesExistingKeysForUser() { 334 int userId = 42; 335 int generationId = 110; 336 int uid = 1009; 337 int status = 120; 338 String alias = "test"; 339 byte[] nonce = getUtf8Bytes("nonce"); 340 byte[] keyMaterial = getUtf8Bytes("keymaterial"); 341 byte[] keyMetadata = null; 342 343 WrappedKey wrappedKey = 344 new WrappedKey(nonce, keyMaterial, keyMetadata, generationId, status); 345 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey); 346 347 WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 348 assertThat(retrievedKey.getRecoveryStatus()).isEqualTo(status); 349 350 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, generationId + 1); 351 352 retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 353 assertThat(retrievedKey.getRecoveryStatus()) 354 .isEqualTo(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE); 355 } 356 357 358 @Test removeUserFromAllTables_removesData()359 public void removeUserFromAllTables_removesData() throws Exception { 360 int userId = 12; 361 int generationId = 24; 362 int[] types = new int[]{1}; 363 int uid = 10009; 364 mRecoverableKeyStoreDb.setRecoveryServiceCertSerial(userId, uid, 365 TEST_ROOT_CERT_ALIAS, 1234L); 366 mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, generationId); 367 mRecoverableKeyStoreDb.setActiveRootOfTrust(userId, uid, "root"); 368 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid, types); 369 370 mRecoverableKeyStoreDb.removeUserFromAllTables(userId); 371 372 // RootOfTrust 373 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 374 TEST_ROOT_CERT_ALIAS)).isNull(); 375 // UserMetadata 376 assertThat(mRecoverableKeyStoreDb.getPlatformKeyGenerationId(userId)).isEqualTo(-1); 377 // RecoveryServiceMetadata 378 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEmpty(); 379 } 380 381 @Test setRecoveryStatus_withSingleKey()382 public void setRecoveryStatus_withSingleKey() { 383 int userId = 12; 384 int uid = 1009; 385 int generationId = 6; 386 int status = 120; 387 int status2 = 121; 388 String alias = "test"; 389 byte[] nonce = getUtf8Bytes("nonce"); 390 byte[] keyMaterial = getUtf8Bytes("keymaterial"); 391 byte[] keyMetadata = null; 392 393 WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, keyMetadata, generationId, 394 status); 395 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey); 396 397 WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 398 assertThat(retrievedKey.getRecoveryStatus()).isEqualTo(status); 399 400 mRecoverableKeyStoreDb.setRecoveryStatus(uid, alias, status2); 401 402 retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 403 assertThat(retrievedKey.getRecoveryStatus()).isEqualTo(status2); 404 } 405 406 @Test getStatusForAllKeys_with3Keys()407 public void getStatusForAllKeys_with3Keys() { 408 int userId = 12; 409 int uid = 1009; 410 int generationId = 6; 411 int status = 120; 412 int status2 = 121; 413 String alias = "test"; 414 String alias2 = "test2"; 415 String alias3 = "test3"; 416 byte[] nonce = getUtf8Bytes("nonce"); 417 byte[] keyMaterial = getUtf8Bytes("keymaterial"); 418 byte[] keyMetadata = null; 419 420 WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, keyMetadata, generationId, 421 status); 422 mRecoverableKeyStoreDb.insertKey(userId, uid, alias2, wrappedKey); 423 WrappedKey wrappedKey2 = new WrappedKey(nonce, keyMaterial, keyMetadata, generationId, 424 status); 425 mRecoverableKeyStoreDb.insertKey(userId, uid, alias3, wrappedKey2); 426 WrappedKey wrappedKeyWithDefaultStatus = new WrappedKey(nonce, keyMaterial, keyMetadata, 427 generationId); 428 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKeyWithDefaultStatus); 429 430 Map<String, Integer> statuses = mRecoverableKeyStoreDb.getStatusForAllKeys(uid); 431 assertThat(statuses).hasSize(3); 432 assertThat(statuses).containsEntry(alias, 433 RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS); 434 assertThat(statuses).containsEntry(alias2, status); 435 assertThat(statuses).containsEntry(alias3, status); 436 437 int updates = mRecoverableKeyStoreDb.setRecoveryStatus(uid, alias, status2); 438 assertThat(updates).isEqualTo(1); 439 updates = mRecoverableKeyStoreDb.setRecoveryStatus(uid, alias3, status2); 440 assertThat(updates).isEqualTo(1); 441 statuses = mRecoverableKeyStoreDb.getStatusForAllKeys(uid); 442 443 assertThat(statuses).hasSize(3); 444 assertThat(statuses).containsEntry(alias, status2); // updated from default 445 assertThat(statuses).containsEntry(alias2, status); 446 assertThat(statuses).containsEntry(alias3, status2); // updated 447 } 448 449 @Test setRecoveryStatus_withEmptyDatabase()450 public void setRecoveryStatus_withEmptyDatabase() throws Exception{ 451 int uid = 1009; 452 String alias = "test"; 453 int status = 120; 454 int updates = mRecoverableKeyStoreDb.setRecoveryStatus(uid, alias, status); 455 assertThat(updates).isEqualTo(0); // database was empty 456 } 457 458 459 @Test getStatusForAllKeys_withEmptyDatabase()460 public void getStatusForAllKeys_withEmptyDatabase() { 461 int uid = 1009; 462 Map<String, Integer> statuses = mRecoverableKeyStoreDb.getStatusForAllKeys(uid); 463 assertThat(statuses).hasSize(0); 464 } 465 466 @Test testInvalidateKeysForUser_withSingleKey()467 public void testInvalidateKeysForUser_withSingleKey() { 468 int userId = 12; 469 int uid = 1009; 470 int generationId = 6; 471 int status = 120; 472 int status2 = 121; 473 String alias = "test"; 474 byte[] nonce = getUtf8Bytes("nonce"); 475 byte[] keyMaterial = getUtf8Bytes("keymaterial"); 476 byte[] keyMetadata = null; 477 478 WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, keyMetadata, generationId, 479 status); 480 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey); 481 482 WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 483 assertThat(retrievedKey.getRecoveryStatus()).isEqualTo(status); 484 485 mRecoverableKeyStoreDb.setRecoveryStatus(uid, alias, status2); 486 mRecoverableKeyStoreDb.invalidateKeysForUser(userId); 487 488 retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 489 assertThat(retrievedKey.getRecoveryStatus()) 490 .isEqualTo(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE); 491 } 492 493 @Test testInvalidateKeysForUserIdOnCustomScreenLock()494 public void testInvalidateKeysForUserIdOnCustomScreenLock() { 495 int userId = 12; 496 int uid = 1009; 497 int generationId = 6; 498 int status = 120; 499 int status2 = 121; 500 String alias = "test"; 501 byte[] nonce = getUtf8Bytes("nonce"); 502 byte[] keyMaterial = getUtf8Bytes("keymaterial"); 503 byte[] keyMetadata = null; 504 505 WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, keyMetadata, generationId, 506 status); 507 mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey); 508 509 WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 510 assertThat(retrievedKey.getRecoveryStatus()).isEqualTo(status); 511 512 mRecoverableKeyStoreDb.setRecoveryStatus(uid, alias, status2); 513 mRecoverableKeyStoreDb.invalidateKeysForUserIdOnCustomScreenLock(userId); 514 515 retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias); 516 assertThat(retrievedKey.getRecoveryStatus()) 517 .isEqualTo(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE); 518 } 519 520 @Test setRecoveryServicePublicKey_replaceOldKey()521 public void setRecoveryServicePublicKey_replaceOldKey() throws Exception { 522 int userId = 12; 523 int uid = 10009; 524 PublicKey pubkey1 = genRandomPublicKey(); 525 PublicKey pubkey2 = genRandomPublicKey(); 526 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, pubkey1); 527 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, pubkey2); 528 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isEqualTo( 529 pubkey2); 530 } 531 532 @Test getRecoveryServicePublicKey_returnsNullIfNoKey()533 public void getRecoveryServicePublicKey_returnsNullIfNoKey() throws Exception { 534 int userId = 12; 535 int uid = 10009; 536 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isNull(); 537 538 mRecoverableKeyStoreDb.setServerParams(userId, uid, SERVER_PARAMS); 539 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isNull(); 540 } 541 542 @Test getRecoveryServicePublicKey_returnsInsertedKey()543 public void getRecoveryServicePublicKey_returnsInsertedKey() throws Exception { 544 int userId = 12; 545 int uid = 10009; 546 PublicKey pubkey = genRandomPublicKey(); 547 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, pubkey); 548 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isEqualTo( 549 pubkey); 550 } 551 552 @Test setRecoveryServiceCertPath_replaceOldValue()553 public void setRecoveryServiceCertPath_replaceOldValue() throws Exception { 554 int userId = 12; 555 int uid = 10009; 556 mRecoverableKeyStoreDb.setRecoveryServiceCertPath(userId, uid, TEST_ROOT_CERT_ALIAS, 557 TestData.CERT_PATH_1); 558 mRecoverableKeyStoreDb.setRecoveryServiceCertPath(userId, uid, TEST_ROOT_CERT_ALIAS, 559 TestData.CERT_PATH_2); 560 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid, 561 TEST_ROOT_CERT_ALIAS)).isEqualTo(TestData.CERT_PATH_2); 562 } 563 564 @Test setRecoveryServiceCertPath_updateValuesForCorrectRootCert()565 public void setRecoveryServiceCertPath_updateValuesForCorrectRootCert() throws Exception { 566 int userId = 12; 567 int uid = 10009; 568 mRecoverableKeyStoreDb.setRecoveryServiceCertPath(userId, uid, TEST_ROOT_CERT_ALIAS, 569 TestData.CERT_PATH_1); 570 mRecoverableKeyStoreDb.setRecoveryServiceCertPath(userId, uid, TEST_ROOT_CERT_ALIAS2, 571 TestData.CERT_PATH_1); 572 573 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid, 574 TEST_ROOT_CERT_ALIAS)).isEqualTo(TestData.CERT_PATH_1); 575 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid, 576 TEST_ROOT_CERT_ALIAS2)).isEqualTo(TestData.CERT_PATH_1); 577 578 mRecoverableKeyStoreDb.setRecoveryServiceCertPath(userId, uid, TEST_ROOT_CERT_ALIAS2, 579 TestData.CERT_PATH_2); 580 581 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid, 582 TEST_ROOT_CERT_ALIAS)).isEqualTo(TestData.CERT_PATH_1); 583 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid, 584 TEST_ROOT_CERT_ALIAS2)).isEqualTo(TestData.CERT_PATH_2); 585 } 586 587 @Test getRecoveryServiceCertPath_returnsNullIfNoValue()588 public void getRecoveryServiceCertPath_returnsNullIfNoValue() throws Exception { 589 int userId = 12; 590 int uid = 10009; 591 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid, 592 TEST_ROOT_CERT_ALIAS)).isNull(); 593 } 594 595 @Test getRecoveryServiceCertPath_returnsInsertedValue()596 public void getRecoveryServiceCertPath_returnsInsertedValue() throws Exception { 597 int userId = 12; 598 int uid = 10009; 599 mRecoverableKeyStoreDb.setRecoveryServiceCertPath(userId, uid, TEST_ROOT_CERT_ALIAS, 600 TestData.CERT_PATH_1); 601 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid, 602 TEST_ROOT_CERT_ALIAS)).isEqualTo(TestData.CERT_PATH_1); 603 } 604 605 @Test setRecoveryServiceCertSerial_replaceOldValue()606 public void setRecoveryServiceCertSerial_replaceOldValue() throws Exception { 607 int userId = 12; 608 int uid = 10009; 609 610 mRecoverableKeyStoreDb.setRecoveryServiceCertSerial(userId, uid, TEST_ROOT_CERT_ALIAS, 1L); 611 mRecoverableKeyStoreDb.setRecoveryServiceCertSerial(userId, uid, TEST_ROOT_CERT_ALIAS, 3L); 612 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 613 TEST_ROOT_CERT_ALIAS)).isEqualTo(3L); 614 } 615 616 @Test setRecoveryServiceCertSerial_updateValuesForCorrectRootCert()617 public void setRecoveryServiceCertSerial_updateValuesForCorrectRootCert() throws Exception { 618 int userId = 12; 619 int uid = 10009; 620 mRecoverableKeyStoreDb.setRecoveryServiceCertSerial(userId, uid, TEST_ROOT_CERT_ALIAS, 1L); 621 mRecoverableKeyStoreDb.setRecoveryServiceCertSerial(userId, uid, TEST_ROOT_CERT_ALIAS2, 1L); 622 623 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 624 TEST_ROOT_CERT_ALIAS)).isEqualTo(1L); 625 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 626 TEST_ROOT_CERT_ALIAS2)).isEqualTo(1L); 627 628 mRecoverableKeyStoreDb.setRecoveryServiceCertSerial(userId, uid, TEST_ROOT_CERT_ALIAS2, 3L); 629 630 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 631 TEST_ROOT_CERT_ALIAS)).isEqualTo(1L); 632 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 633 TEST_ROOT_CERT_ALIAS2)).isEqualTo(3L); 634 } 635 636 @Test getRecoveryServiceCertSerial_returnsNullIfNoValue()637 public void getRecoveryServiceCertSerial_returnsNullIfNoValue() throws Exception { 638 int userId = 12; 639 int uid = 10009; 640 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 641 TEST_ROOT_CERT_ALIAS)).isNull(); 642 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 643 TEST_ROOT_CERT_ALIAS2)).isNull(); 644 } 645 646 @Test getRecoveryServiceCertSerial_returnsInsertedValue()647 public void getRecoveryServiceCertSerial_returnsInsertedValue() throws Exception { 648 int userId = 12; 649 int uid = 10009; 650 mRecoverableKeyStoreDb.setRecoveryServiceCertSerial(userId, uid, 651 TEST_ROOT_CERT_ALIAS, 1234L); 652 assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid, 653 TEST_ROOT_CERT_ALIAS)).isEqualTo(1234L); 654 } 655 656 @Test getRecoveryAgents_returnsUidIfSet()657 public void getRecoveryAgents_returnsUidIfSet() throws Exception { 658 int userId = 12; 659 int uid = 190992; 660 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, genRandomPublicKey()); 661 662 assertThat(mRecoverableKeyStoreDb.getRecoveryAgents(userId)).contains(uid); 663 } 664 665 @Test getRecoveryAgents_returnsEmptyListIfThereAreNoAgents()666 public void getRecoveryAgents_returnsEmptyListIfThereAreNoAgents() throws Exception { 667 int userId = 12; 668 assertThat(mRecoverableKeyStoreDb.getRecoveryAgents(userId)).isEmpty(); 669 assertThat(mRecoverableKeyStoreDb.getRecoveryAgents(userId)).isNotNull(); 670 } 671 672 @Test getRecoveryAgents_withTwoAgents()673 public void getRecoveryAgents_withTwoAgents() throws Exception { 674 int userId = 12; 675 int uid1 = 190992; 676 int uid2 = 190993; 677 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid1, genRandomPublicKey()); 678 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid2, genRandomPublicKey()); 679 List<Integer> agents = mRecoverableKeyStoreDb.getRecoveryAgents(userId); 680 681 assertThat(agents).hasSize(2); 682 assertThat(agents).contains(uid1); 683 assertThat(agents).contains(uid2); 684 } 685 686 @Test setActiveRootOfTrust_emptyDefaultValue()687 public void setActiveRootOfTrust_emptyDefaultValue() throws Exception { 688 int userId = 12; 689 int uid = 10009; 690 assertThat(mRecoverableKeyStoreDb.getActiveRootOfTrust(userId, uid)).isEqualTo(null); 691 } 692 693 @Test setActiveRootOfTrust_updateValue()694 public void setActiveRootOfTrust_updateValue() throws Exception { 695 int userId = 12; 696 int uid = 10009; 697 mRecoverableKeyStoreDb.setActiveRootOfTrust(userId, uid, "root"); 698 assertThat(mRecoverableKeyStoreDb.getActiveRootOfTrust(userId, uid)).isEqualTo("root"); 699 700 mRecoverableKeyStoreDb.setActiveRootOfTrust(userId, uid, "root2"); 701 assertThat(mRecoverableKeyStoreDb.getActiveRootOfTrust(userId, uid)).isEqualTo("root2"); 702 } 703 704 @Test setRecoverySecretTypes_emptyDefaultValue()705 public void setRecoverySecretTypes_emptyDefaultValue() throws Exception { 706 int userId = 12; 707 int uid = 10009; 708 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEqualTo( 709 new int[]{}); // default 710 } 711 712 @Test setRecoverySecretTypes_updateValue()713 public void setRecoverySecretTypes_updateValue() throws Exception { 714 int userId = 12; 715 int uid = 10009; 716 int[] types1 = new int[]{1}; 717 int[] types2 = new int[]{2}; 718 719 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid, types1); 720 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEqualTo(types1); 721 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid, types2); 722 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEqualTo(types2); 723 } 724 725 @Test setRecoverySecretTypes_withMultiElementArrays()726 public void setRecoverySecretTypes_withMultiElementArrays() throws Exception { 727 int userId = 12; 728 int uid = 10009; 729 int[] types1 = new int[]{11, 2000}; 730 int[] types2 = new int[]{1, 2, 3}; 731 int[] types3 = new int[]{}; 732 733 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid, types1); 734 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEqualTo( 735 types1); 736 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid, types2); 737 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEqualTo( 738 types2); 739 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid, types3); 740 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEqualTo( 741 types3); 742 } 743 744 @Test setRecoverySecretTypes_withDifferentUid()745 public void setRecoverySecretTypes_withDifferentUid() throws Exception { 746 int userId = 12; 747 int uid1 = 10011; 748 int uid2 = 10012; 749 int[] types1 = new int[]{1}; 750 int[] types2 = new int[]{2}; 751 752 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid1, types1); 753 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid2, types2); 754 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid1)).isEqualTo( 755 types1); 756 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid2)).isEqualTo( 757 types2); 758 } 759 760 @Test setRecoveryServiceMetadataMethods()761 public void setRecoveryServiceMetadataMethods() throws Exception { 762 int userId = 12; 763 int uid = 10009; 764 765 PublicKey pubkey1 = genRandomPublicKey(); 766 int[] types1 = new int[]{1}; 767 768 PublicKey pubkey2 = genRandomPublicKey(); 769 int[] types2 = new int[]{2}; 770 771 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, pubkey1); 772 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid, types1); 773 mRecoverableKeyStoreDb.setServerParams(userId, uid, SERVER_PARAMS); 774 775 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEqualTo( 776 types1); 777 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isEqualTo( 778 SERVER_PARAMS); 779 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isEqualTo( 780 pubkey1); 781 782 // Check that the methods don't interfere with each other. 783 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, pubkey2); 784 mRecoverableKeyStoreDb.setRecoverySecretTypes(userId, uid, types2); 785 mRecoverableKeyStoreDb.setServerParams(userId, uid, SERVER_PARAMS2); 786 787 assertThat(mRecoverableKeyStoreDb.getRecoverySecretTypes(userId, uid)).isEqualTo( 788 types2); 789 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isEqualTo( 790 SERVER_PARAMS2); 791 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isEqualTo( 792 pubkey2); 793 } 794 795 @Test setServerParams_replaceOldValue()796 public void setServerParams_replaceOldValue() throws Exception { 797 int userId = 12; 798 int uid = 10009; 799 800 mRecoverableKeyStoreDb.setServerParams(userId, uid, SERVER_PARAMS); 801 mRecoverableKeyStoreDb.setServerParams(userId, uid, SERVER_PARAMS2); 802 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isEqualTo( 803 SERVER_PARAMS2); 804 } 805 806 @Test getServerParams_returnsNullIfNoValue()807 public void getServerParams_returnsNullIfNoValue() throws Exception { 808 int userId = 12; 809 int uid = 10009; 810 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isNull(); 811 812 PublicKey pubkey = genRandomPublicKey(); 813 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, pubkey); 814 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isNull(); 815 } 816 817 @Test getServerParams_returnsInsertedValue()818 public void getServerParams_returnsInsertedValue() throws Exception { 819 int userId = 12; 820 int uid = 10009; 821 mRecoverableKeyStoreDb.setServerParams(userId, uid, SERVER_PARAMS); 822 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isEqualTo(SERVER_PARAMS); 823 } 824 825 @Test setCounterId_defaultValueAndTwoUpdates()826 public void setCounterId_defaultValueAndTwoUpdates() throws Exception { 827 int userId = 12; 828 int uid = 10009; 829 long value1 = 111L; 830 long value2 = 222L; 831 assertThat(mRecoverableKeyStoreDb.getCounterId(userId, uid)).isNull(); 832 833 mRecoverableKeyStoreDb.setCounterId(userId, uid, value1); 834 assertThat(mRecoverableKeyStoreDb.getCounterId(userId, uid)).isEqualTo( 835 value1); 836 837 mRecoverableKeyStoreDb.setCounterId(userId, uid, value2); 838 assertThat(mRecoverableKeyStoreDb.getCounterId(userId, uid)).isEqualTo( 839 value2); 840 } 841 842 @Test setSnapshotVersion_defaultValueAndTwoUpdates()843 public void setSnapshotVersion_defaultValueAndTwoUpdates() throws Exception { 844 int userId = 12; 845 int uid = 10009; 846 long value1 = 111L; 847 long value2 = 222L; 848 assertThat(mRecoverableKeyStoreDb.getSnapshotVersion(userId, uid)).isNull(); 849 mRecoverableKeyStoreDb.setSnapshotVersion(userId, uid, value1); 850 assertThat(mRecoverableKeyStoreDb.getSnapshotVersion(userId, uid)).isEqualTo( 851 value1); 852 mRecoverableKeyStoreDb.setSnapshotVersion(userId, uid, value2); 853 assertThat(mRecoverableKeyStoreDb.getSnapshotVersion(userId, uid)).isEqualTo( 854 value2); 855 } 856 857 @Test setShouldCreateSnapshot_defaultValueAndTwoUpdates()858 public void setShouldCreateSnapshot_defaultValueAndTwoUpdates() throws Exception { 859 int userId = 12; 860 int uid = 10009; 861 boolean value1 = true; 862 boolean value2 = false; 863 assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isEqualTo(false); 864 mRecoverableKeyStoreDb.setShouldCreateSnapshot(userId, uid, value1); 865 assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isEqualTo(value1); 866 mRecoverableKeyStoreDb.setShouldCreateSnapshot(userId, uid, value2); 867 assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isEqualTo( 868 value2); 869 } 870 871 @Test setRecoveryServiceMetadataEntry_allowsAUserToHaveTwoUids()872 public void setRecoveryServiceMetadataEntry_allowsAUserToHaveTwoUids() throws Exception { 873 int userId = 12; 874 int uid1 = 10009; 875 int uid2 = 20009; 876 PublicKey pubkey = genRandomPublicKey(); 877 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid1, pubkey); 878 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid2, pubkey); 879 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid1)).isEqualTo( 880 pubkey); 881 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid2)).isEqualTo( 882 pubkey); 883 } 884 885 @Test setRecoveryServiceMetadataEntry_allowsTwoUsersToHaveTheSameUid()886 public void setRecoveryServiceMetadataEntry_allowsTwoUsersToHaveTheSameUid() throws Exception { 887 int userId1 = 12; 888 int userId2 = 23; 889 int uid = 10009; 890 PublicKey pubkey = genRandomPublicKey(); 891 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId1, uid, pubkey); 892 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId2, uid, pubkey); 893 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId1, uid)).isEqualTo( 894 pubkey); 895 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId2, uid)).isEqualTo( 896 pubkey); 897 } 898 899 @Test setRecoveryServiceMetadataEntry_updatesColumnsSeparately()900 public void setRecoveryServiceMetadataEntry_updatesColumnsSeparately() throws Exception { 901 int userId = 12; 902 int uid = 10009; 903 PublicKey pubkey1 = genRandomPublicKey(); 904 PublicKey pubkey2 = genRandomPublicKey(); 905 906 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, pubkey1); 907 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isEqualTo( 908 pubkey1); 909 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isNull(); 910 911 mRecoverableKeyStoreDb.setServerParams(userId, uid, SERVER_PARAMS); 912 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isEqualTo( 913 pubkey1); 914 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isEqualTo(SERVER_PARAMS); 915 916 mRecoverableKeyStoreDb.setRecoveryServicePublicKey(userId, uid, pubkey2); 917 assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isEqualTo( 918 pubkey2); 919 assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isEqualTo(SERVER_PARAMS); 920 } 921 getUtf8Bytes(String s)922 private static byte[] getUtf8Bytes(String s) { 923 return s.getBytes(StandardCharsets.UTF_8); 924 } 925 genRandomPublicKey()926 private static PublicKey genRandomPublicKey() throws Exception { 927 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); 928 keyPairGenerator.initialize(new ECGenParameterSpec("secp256r1")); 929 return keyPairGenerator.generateKeyPair().getPublic(); 930 } 931 } 932