Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +3 −0 Original line number Diff line number Diff line Loading @@ -1284,6 +1284,7 @@ public class LockSettingsService extends ILockSettings.Stub { fixateNewestUserKeyAuth(userId); synchronizeUnifiedWorkChallengeForProfiles(userId, null); notifyActivePasswordMetricsAvailable(null, userId); mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId); return; } if (credential == null) { Loading Loading @@ -1333,6 +1334,8 @@ public class LockSettingsService extends ILockSettings.Stub { .verifyChallenge(userId, 0, willStore.hash, credential.getBytes()); setUserKeyProtection(userId, credential, convertResponse(gkResponse)); fixateNewestUserKeyAuth(userId); mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId); // Refresh the auth token doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */); synchronizeUnifiedWorkChallengeForProfiles(userId, null); Loading services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java +75 −23 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ public class KeySyncTask implements Runnable { private final int mUserId; private final int mCredentialType; private final String mCredential; private final boolean mCredentialUpdated; private final PlatformKeyManager.Factory mPlatformKeyManagerFactory; private final RecoverySnapshotStorage mRecoverySnapshotStorage; private final RecoverySnapshotListenersStorage mSnapshotListenersStorage; Loading @@ -80,7 +81,8 @@ public class KeySyncTask implements Runnable { RecoverySnapshotListenersStorage recoverySnapshotListenersStorage, int userId, int credentialType, String credential String credential, boolean credentialUpdated ) throws NoSuchAlgorithmException, KeyStoreException, InsecureUserException { return new KeySyncTask( recoverableKeyStoreDb, Loading @@ -89,6 +91,7 @@ public class KeySyncTask implements Runnable { userId, credentialType, credential, credentialUpdated, () -> PlatformKeyManager.getInstance(context, recoverableKeyStoreDb)); } Loading @@ -99,6 +102,7 @@ public class KeySyncTask implements Runnable { * @param userId The uid of the user whose profile has been unlocked. * @param credentialType The type of credential - i.e., pattern or password. * @param credential The credential, encoded as a {@link String}. * @param credentialUpdated signals weather credentials were updated. * @param platformKeyManagerFactory Instantiates a {@link PlatformKeyManager} for the user. * This is a factory to enable unit testing, as otherwise it would be impossible to test * without a screen unlock occurring! Loading @@ -111,12 +115,14 @@ public class KeySyncTask implements Runnable { int userId, int credentialType, String credential, boolean credentialUpdated, PlatformKeyManager.Factory platformKeyManagerFactory) { mSnapshotListenersStorage = recoverySnapshotListenersStorage; mRecoverableKeyStoreDb = recoverableKeyStoreDb; mUserId = userId; mCredentialType = credentialType; mCredential = credential; mCredentialUpdated = credentialUpdated; mPlatformKeyManagerFactory = platformKeyManagerFactory; mRecoverySnapshotStorage = snapshotStorage; } Loading @@ -124,29 +130,44 @@ public class KeySyncTask implements Runnable { @Override public void run() { try { // Only one task is active If user unlocks phone many times in a short time interval. synchronized(KeySyncTask.class) { syncKeys(); } } catch (Exception e) { Log.e(TAG, "Unexpected exception thrown during KeySyncTask", e); } } private void syncKeys() { if (!isSyncPending()) { Log.d(TAG, "Key sync not needed."); if (mCredentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) { // Application keys for the user will not be available for sync. Log.w(TAG, "Credentials are not set for user " + mUserId); return; } int recoveryAgentUid = mRecoverableKeyStoreDb.getRecoveryAgentUid(mUserId); if (recoveryAgentUid == -1) { List<Integer> recoveryAgents = mRecoverableKeyStoreDb.getRecoveryAgents(mUserId); for (int uid : recoveryAgents) { syncKeysForAgent(uid); } if (recoveryAgents.isEmpty()) { Log.w(TAG, "No recovery agent initialized for user " + mUserId); } } private void syncKeysForAgent(int recoveryAgentUid) { if (!shoudCreateSnapshot(recoveryAgentUid)) { Log.d(TAG, "Key sync not needed."); return; } if (!mSnapshotListenersStorage.hasListener(recoveryAgentUid)) { Log.w(TAG, "No pending intent registered for recovery agent " + recoveryAgentUid); return; } PublicKey publicKey = getVaultPublicKey(); PublicKey publicKey = mRecoverableKeyStoreDb.getRecoveryServicePublicKey(mUserId, recoveryAgentUid); if (publicKey == null) { Log.w(TAG, "Not initialized for KeySync: no public key set. Cancelling task."); return; Loading @@ -163,7 +184,7 @@ public class KeySyncTask implements Runnable { Map<String, SecretKey> rawKeys; try { rawKeys = getKeysToSync(); rawKeys = getKeysToSync(recoveryAgentUid); } catch (GeneralSecurityException e) { Log.e(TAG, "Failed to load recoverable keys for sync", e); return; Loading Loading @@ -196,10 +217,19 @@ public class KeySyncTask implements Runnable { return; } // TODO: where do we get counter_id from here? Long counterId; // counter id is generated exactly once for each credentials value. if (mCredentialUpdated) { counterId = generateAndStoreCounterId(recoveryAgentUid); } else { counterId = mRecoverableKeyStoreDb.getCounterId(mUserId, recoveryAgentUid); if (counterId == null) { counterId = generateAndStoreCounterId(recoveryAgentUid); } } byte[] vaultParams = KeySyncUtils.packVaultParams( publicKey, /*counterId=*/ 1, counterId, TRUSTED_HARDWARE_MAX_ATTEMPTS, deviceId); Loading @@ -217,7 +247,7 @@ public class KeySyncTask implements Runnable { Log.e(TAG,"Could not encrypt with recovery key", e); return; } // TODO: store raw data in RecoveryServiceMetadataEntry and generate Parcelables later KeyStoreRecoveryMetadata metadata = new KeyStoreRecoveryMetadata( /*userSecretType=*/ TYPE_LOCKSCREEN, /*lockScreenUiFormat=*/ mCredentialType, Loading @@ -226,40 +256,62 @@ public class KeySyncTask implements Runnable { ArrayList<KeyStoreRecoveryMetadata> metadataList = new ArrayList<>(); metadataList.add(metadata); // TODO: implement snapshot version mRecoverySnapshotStorage.put(mUserId, new KeyStoreRecoveryData( /*snapshotVersion=*/ 1, int snapshotVersion = incrementSnapshotVersion(recoveryAgentUid); // If application keys are not updated, snapshot will not be created on next unlock. mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, false); mRecoverySnapshotStorage.put(recoveryAgentUid, new KeyStoreRecoveryData( snapshotVersion, /*recoveryMetadata=*/ metadataList, /*applicationKeyBlobs=*/ createApplicationKeyEntries(encryptedApplicationKeys), /*encryptedRecoveryKeyblob=*/ encryptedRecoveryKey)); mSnapshotListenersStorage.recoverySnapshotAvailable(recoveryAgentUid); } private PublicKey getVaultPublicKey() { return mRecoverableKeyStoreDb.getRecoveryServicePublicKey(mUserId); @VisibleForTesting int incrementSnapshotVersion(int recoveryAgentUid) { Long snapshotVersion = mRecoverableKeyStoreDb.getSnapshotVersion(mUserId, recoveryAgentUid); snapshotVersion = snapshotVersion == null ? 1 : snapshotVersion + 1; mRecoverableKeyStoreDb.setSnapshotVersion(mUserId, recoveryAgentUid, snapshotVersion); return snapshotVersion.intValue(); } private long generateAndStoreCounterId(int recoveryAgentUid) { long counter = new SecureRandom().nextLong(); mRecoverableKeyStoreDb.setCounterId(mUserId, recoveryAgentUid, counter); return counter; } /** * Returns all of the recoverable keys for the user. */ private Map<String, SecretKey> getKeysToSync() private Map<String, SecretKey> getKeysToSync(int recoveryAgentUid) throws InsecureUserException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, NoSuchPaddingException, BadPlatformKeyException { PlatformKeyManager platformKeyManager = mPlatformKeyManagerFactory.newInstance(); PlatformDecryptionKey decryptKey = platformKeyManager.getDecryptKey(mUserId); Map<String, WrappedKey> wrappedKeys = mRecoverableKeyStoreDb.getAllKeys( mUserId, decryptKey.getGenerationId()); mUserId, recoveryAgentUid, decryptKey.getGenerationId()); return WrappedKey.unwrapKeys(decryptKey, wrappedKeys); } /** * Returns {@code true} if a sync is pending. * @param recoveryAgentUid uid of the recovery agent. */ private boolean isSyncPending() { // TODO: implement properly. For now just always syncing if the user has any recoverable // keys. We need to keep track of when the store's state actually changes. return !mRecoverableKeyStoreDb.getAllKeys( mUserId, mRecoverableKeyStoreDb.getPlatformKeyGenerationId(mUserId)).isEmpty(); private boolean shoudCreateSnapshot(int recoveryAgentUid) { if (mCredentialUpdated) { // Sync credential if at least one snapshot was created. if (mRecoverableKeyStoreDb.getSnapshotVersion(mUserId, recoveryAgentUid) != null) { mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, true); return true; } } return mRecoverableKeyStoreDb.getShouldCreateSnapshot(mUserId, recoveryAgentUid); } /** Loading services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java +1 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ public class RecoverableKeyGenerator { Locale.US, "Failed writing (%d, %s) to database.", uid, alias)); } mDatabase.setShouldCreateSnapshot(userId, uid, true); return key.getEncoded(); } } services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +37 −7 Original line number Diff line number Diff line Loading @@ -174,8 +174,8 @@ public class RecoverableKeyStoreManager { public @NonNull KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account) throws RemoteException { checkRecoverKeyStorePermission(); KeyStoreRecoveryData snapshot = mSnapshotStorage.get(UserHandle.getCallingUserId()); int uid = Binder.getCallingUid(); KeyStoreRecoveryData snapshot = mSnapshotStorage.get(uid); if (snapshot == null) { throw new ServiceSpecificException(RecoverableKeyStoreLoader.ERROR_NO_SNAPSHOT_PENDING); } Loading Loading @@ -433,7 +433,13 @@ public class RecoverableKeyStoreManager { } public void removeKey(@NonNull String alias) throws RemoteException { mDatabase.removeKey(Binder.getCallingUid(), alias); int uid = Binder.getCallingUid(); int userId = UserHandle.getCallingUserId(); boolean wasRemoved = mDatabase.removeKey(uid, alias); if (wasRemoved) { mDatabase.setShouldCreateSnapshot(userId, uid, true); } } private byte[] decryptRecoveryKey( Loading Loading @@ -505,7 +511,8 @@ public class RecoverableKeyStoreManager { mListenersStorage, userId, storedHashType, credential)); credential, /*credentialUpdated=*/ false)); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Should never happen - algorithm unavailable for KeySync", e); } catch (KeyStoreException e) { Loading @@ -515,12 +522,35 @@ public class RecoverableKeyStoreManager { } } /** This function can only be used inside LockSettingsService. */ /** * This function can only be used inside LockSettingsService. * @param storedHashType from {@code CredentialHash} * @param credential - unencrypted String * @param userId for the user whose lock screen credentials were changed. * @hide */ public void lockScreenSecretChanged( @KeyStoreRecoveryMetadata.LockScreenUiFormat int type, int storedHashType, @Nullable String credential, int userId) { throw new UnsupportedOperationException(); // So as not to block the critical path unlocking the phone, defer to another thread. try { mExecutorService.execute(KeySyncTask.newInstance( mContext, mDatabase, mSnapshotStorage, mListenersStorage, userId, storedHashType, credential, /*credentialUpdated=*/ true)); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Should never happen - algorithm unavailable for KeySync", e); } catch (KeyStoreException e) { Log.e(TAG, "Key store error encountered during recoverable key sync", e); } catch (InsecureUserException e) { Log.wtf(TAG, "Impossible - insecure user, but user just entered lock screen", e); } } private void checkRecoverKeyStorePermission() { Loading services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java +174 −39 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +3 −0 Original line number Diff line number Diff line Loading @@ -1284,6 +1284,7 @@ public class LockSettingsService extends ILockSettings.Stub { fixateNewestUserKeyAuth(userId); synchronizeUnifiedWorkChallengeForProfiles(userId, null); notifyActivePasswordMetricsAvailable(null, userId); mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId); return; } if (credential == null) { Loading Loading @@ -1333,6 +1334,8 @@ public class LockSettingsService extends ILockSettings.Stub { .verifyChallenge(userId, 0, willStore.hash, credential.getBytes()); setUserKeyProtection(userId, credential, convertResponse(gkResponse)); fixateNewestUserKeyAuth(userId); mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId); // Refresh the auth token doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */); synchronizeUnifiedWorkChallengeForProfiles(userId, null); Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java +75 −23 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ public class KeySyncTask implements Runnable { private final int mUserId; private final int mCredentialType; private final String mCredential; private final boolean mCredentialUpdated; private final PlatformKeyManager.Factory mPlatformKeyManagerFactory; private final RecoverySnapshotStorage mRecoverySnapshotStorage; private final RecoverySnapshotListenersStorage mSnapshotListenersStorage; Loading @@ -80,7 +81,8 @@ public class KeySyncTask implements Runnable { RecoverySnapshotListenersStorage recoverySnapshotListenersStorage, int userId, int credentialType, String credential String credential, boolean credentialUpdated ) throws NoSuchAlgorithmException, KeyStoreException, InsecureUserException { return new KeySyncTask( recoverableKeyStoreDb, Loading @@ -89,6 +91,7 @@ public class KeySyncTask implements Runnable { userId, credentialType, credential, credentialUpdated, () -> PlatformKeyManager.getInstance(context, recoverableKeyStoreDb)); } Loading @@ -99,6 +102,7 @@ public class KeySyncTask implements Runnable { * @param userId The uid of the user whose profile has been unlocked. * @param credentialType The type of credential - i.e., pattern or password. * @param credential The credential, encoded as a {@link String}. * @param credentialUpdated signals weather credentials were updated. * @param platformKeyManagerFactory Instantiates a {@link PlatformKeyManager} for the user. * This is a factory to enable unit testing, as otherwise it would be impossible to test * without a screen unlock occurring! Loading @@ -111,12 +115,14 @@ public class KeySyncTask implements Runnable { int userId, int credentialType, String credential, boolean credentialUpdated, PlatformKeyManager.Factory platformKeyManagerFactory) { mSnapshotListenersStorage = recoverySnapshotListenersStorage; mRecoverableKeyStoreDb = recoverableKeyStoreDb; mUserId = userId; mCredentialType = credentialType; mCredential = credential; mCredentialUpdated = credentialUpdated; mPlatformKeyManagerFactory = platformKeyManagerFactory; mRecoverySnapshotStorage = snapshotStorage; } Loading @@ -124,29 +130,44 @@ public class KeySyncTask implements Runnable { @Override public void run() { try { // Only one task is active If user unlocks phone many times in a short time interval. synchronized(KeySyncTask.class) { syncKeys(); } } catch (Exception e) { Log.e(TAG, "Unexpected exception thrown during KeySyncTask", e); } } private void syncKeys() { if (!isSyncPending()) { Log.d(TAG, "Key sync not needed."); if (mCredentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) { // Application keys for the user will not be available for sync. Log.w(TAG, "Credentials are not set for user " + mUserId); return; } int recoveryAgentUid = mRecoverableKeyStoreDb.getRecoveryAgentUid(mUserId); if (recoveryAgentUid == -1) { List<Integer> recoveryAgents = mRecoverableKeyStoreDb.getRecoveryAgents(mUserId); for (int uid : recoveryAgents) { syncKeysForAgent(uid); } if (recoveryAgents.isEmpty()) { Log.w(TAG, "No recovery agent initialized for user " + mUserId); } } private void syncKeysForAgent(int recoveryAgentUid) { if (!shoudCreateSnapshot(recoveryAgentUid)) { Log.d(TAG, "Key sync not needed."); return; } if (!mSnapshotListenersStorage.hasListener(recoveryAgentUid)) { Log.w(TAG, "No pending intent registered for recovery agent " + recoveryAgentUid); return; } PublicKey publicKey = getVaultPublicKey(); PublicKey publicKey = mRecoverableKeyStoreDb.getRecoveryServicePublicKey(mUserId, recoveryAgentUid); if (publicKey == null) { Log.w(TAG, "Not initialized for KeySync: no public key set. Cancelling task."); return; Loading @@ -163,7 +184,7 @@ public class KeySyncTask implements Runnable { Map<String, SecretKey> rawKeys; try { rawKeys = getKeysToSync(); rawKeys = getKeysToSync(recoveryAgentUid); } catch (GeneralSecurityException e) { Log.e(TAG, "Failed to load recoverable keys for sync", e); return; Loading Loading @@ -196,10 +217,19 @@ public class KeySyncTask implements Runnable { return; } // TODO: where do we get counter_id from here? Long counterId; // counter id is generated exactly once for each credentials value. if (mCredentialUpdated) { counterId = generateAndStoreCounterId(recoveryAgentUid); } else { counterId = mRecoverableKeyStoreDb.getCounterId(mUserId, recoveryAgentUid); if (counterId == null) { counterId = generateAndStoreCounterId(recoveryAgentUid); } } byte[] vaultParams = KeySyncUtils.packVaultParams( publicKey, /*counterId=*/ 1, counterId, TRUSTED_HARDWARE_MAX_ATTEMPTS, deviceId); Loading @@ -217,7 +247,7 @@ public class KeySyncTask implements Runnable { Log.e(TAG,"Could not encrypt with recovery key", e); return; } // TODO: store raw data in RecoveryServiceMetadataEntry and generate Parcelables later KeyStoreRecoveryMetadata metadata = new KeyStoreRecoveryMetadata( /*userSecretType=*/ TYPE_LOCKSCREEN, /*lockScreenUiFormat=*/ mCredentialType, Loading @@ -226,40 +256,62 @@ public class KeySyncTask implements Runnable { ArrayList<KeyStoreRecoveryMetadata> metadataList = new ArrayList<>(); metadataList.add(metadata); // TODO: implement snapshot version mRecoverySnapshotStorage.put(mUserId, new KeyStoreRecoveryData( /*snapshotVersion=*/ 1, int snapshotVersion = incrementSnapshotVersion(recoveryAgentUid); // If application keys are not updated, snapshot will not be created on next unlock. mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, false); mRecoverySnapshotStorage.put(recoveryAgentUid, new KeyStoreRecoveryData( snapshotVersion, /*recoveryMetadata=*/ metadataList, /*applicationKeyBlobs=*/ createApplicationKeyEntries(encryptedApplicationKeys), /*encryptedRecoveryKeyblob=*/ encryptedRecoveryKey)); mSnapshotListenersStorage.recoverySnapshotAvailable(recoveryAgentUid); } private PublicKey getVaultPublicKey() { return mRecoverableKeyStoreDb.getRecoveryServicePublicKey(mUserId); @VisibleForTesting int incrementSnapshotVersion(int recoveryAgentUid) { Long snapshotVersion = mRecoverableKeyStoreDb.getSnapshotVersion(mUserId, recoveryAgentUid); snapshotVersion = snapshotVersion == null ? 1 : snapshotVersion + 1; mRecoverableKeyStoreDb.setSnapshotVersion(mUserId, recoveryAgentUid, snapshotVersion); return snapshotVersion.intValue(); } private long generateAndStoreCounterId(int recoveryAgentUid) { long counter = new SecureRandom().nextLong(); mRecoverableKeyStoreDb.setCounterId(mUserId, recoveryAgentUid, counter); return counter; } /** * Returns all of the recoverable keys for the user. */ private Map<String, SecretKey> getKeysToSync() private Map<String, SecretKey> getKeysToSync(int recoveryAgentUid) throws InsecureUserException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, NoSuchPaddingException, BadPlatformKeyException { PlatformKeyManager platformKeyManager = mPlatformKeyManagerFactory.newInstance(); PlatformDecryptionKey decryptKey = platformKeyManager.getDecryptKey(mUserId); Map<String, WrappedKey> wrappedKeys = mRecoverableKeyStoreDb.getAllKeys( mUserId, decryptKey.getGenerationId()); mUserId, recoveryAgentUid, decryptKey.getGenerationId()); return WrappedKey.unwrapKeys(decryptKey, wrappedKeys); } /** * Returns {@code true} if a sync is pending. * @param recoveryAgentUid uid of the recovery agent. */ private boolean isSyncPending() { // TODO: implement properly. For now just always syncing if the user has any recoverable // keys. We need to keep track of when the store's state actually changes. return !mRecoverableKeyStoreDb.getAllKeys( mUserId, mRecoverableKeyStoreDb.getPlatformKeyGenerationId(mUserId)).isEmpty(); private boolean shoudCreateSnapshot(int recoveryAgentUid) { if (mCredentialUpdated) { // Sync credential if at least one snapshot was created. if (mRecoverableKeyStoreDb.getSnapshotVersion(mUserId, recoveryAgentUid) != null) { mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, true); return true; } } return mRecoverableKeyStoreDb.getShouldCreateSnapshot(mUserId, recoveryAgentUid); } /** Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java +1 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ public class RecoverableKeyGenerator { Locale.US, "Failed writing (%d, %s) to database.", uid, alias)); } mDatabase.setShouldCreateSnapshot(userId, uid, true); return key.getEncoded(); } }
services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +37 −7 Original line number Diff line number Diff line Loading @@ -174,8 +174,8 @@ public class RecoverableKeyStoreManager { public @NonNull KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account) throws RemoteException { checkRecoverKeyStorePermission(); KeyStoreRecoveryData snapshot = mSnapshotStorage.get(UserHandle.getCallingUserId()); int uid = Binder.getCallingUid(); KeyStoreRecoveryData snapshot = mSnapshotStorage.get(uid); if (snapshot == null) { throw new ServiceSpecificException(RecoverableKeyStoreLoader.ERROR_NO_SNAPSHOT_PENDING); } Loading Loading @@ -433,7 +433,13 @@ public class RecoverableKeyStoreManager { } public void removeKey(@NonNull String alias) throws RemoteException { mDatabase.removeKey(Binder.getCallingUid(), alias); int uid = Binder.getCallingUid(); int userId = UserHandle.getCallingUserId(); boolean wasRemoved = mDatabase.removeKey(uid, alias); if (wasRemoved) { mDatabase.setShouldCreateSnapshot(userId, uid, true); } } private byte[] decryptRecoveryKey( Loading Loading @@ -505,7 +511,8 @@ public class RecoverableKeyStoreManager { mListenersStorage, userId, storedHashType, credential)); credential, /*credentialUpdated=*/ false)); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Should never happen - algorithm unavailable for KeySync", e); } catch (KeyStoreException e) { Loading @@ -515,12 +522,35 @@ public class RecoverableKeyStoreManager { } } /** This function can only be used inside LockSettingsService. */ /** * This function can only be used inside LockSettingsService. * @param storedHashType from {@code CredentialHash} * @param credential - unencrypted String * @param userId for the user whose lock screen credentials were changed. * @hide */ public void lockScreenSecretChanged( @KeyStoreRecoveryMetadata.LockScreenUiFormat int type, int storedHashType, @Nullable String credential, int userId) { throw new UnsupportedOperationException(); // So as not to block the critical path unlocking the phone, defer to another thread. try { mExecutorService.execute(KeySyncTask.newInstance( mContext, mDatabase, mSnapshotStorage, mListenersStorage, userId, storedHashType, credential, /*credentialUpdated=*/ true)); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Should never happen - algorithm unavailable for KeySync", e); } catch (KeyStoreException e) { Log.e(TAG, "Key store error encountered during recoverable key sync", e); } catch (InsecureUserException e) { Log.wtf(TAG, "Impossible - insecure user, but user just entered lock screen", e); } } private void checkRecoverKeyStorePermission() { Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java +174 −39 File changed.Preview size limit exceeded, changes collapsed. Show changes