Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +15 −11 Original line number Diff line number Diff line Loading @@ -1741,6 +1741,10 @@ public class LockSettingsService extends ILockSettings.Stub { } } } // Use credentials to create recoverable keystore snapshot. mRecoverableKeyStoreManager.lockScreenSecretAvailable(storedHash.type, credential, userId); } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { if (response.getTimeout() > 0) { requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId); Loading Loading @@ -1931,14 +1935,14 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void initRecoveryService(@NonNull String rootCertificateAlias, @NonNull byte[] signedPublicKeyList, int userId) @NonNull byte[] signedPublicKeyList, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.initRecoveryService(rootCertificateAlias, signedPublicKeyList, userId); } @Override public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account, int userId) public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account, @UserIdInt int userId) throws RemoteException { return mRecoverableKeyStoreManager.getRecoveryData(account, userId); } Loading @@ -1953,13 +1957,14 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override public void setServerParameters(long serverParameters, int userId) throws RemoteException { public void setServerParameters(long serverParameters, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.setServerParameters(serverParameters, userId); } @Override public void setRecoveryStatus(@NonNull String packageName, @Nullable String[] aliases, int status, int userId) throws RemoteException { int status, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.setRecoveryStatus(packageName, aliases, status, userId); } Loading @@ -1969,25 +1974,24 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void setRecoverySecretTypes(@NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] secretTypes, int userId) throws RemoteException { int[] secretTypes, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.setRecoverySecretTypes(secretTypes, userId); } @Override public int[] getRecoverySecretTypes(int userId) throws RemoteException { public int[] getRecoverySecretTypes(@UserIdInt int userId) throws RemoteException { return mRecoverableKeyStoreManager.getRecoverySecretTypes(userId); } @Override public int[] getPendingRecoverySecretTypes(int userId) throws RemoteException { public int[] getPendingRecoverySecretTypes(@UserIdInt int userId) throws RemoteException { throw new SecurityException("Not implemented"); } @Override public void recoverySecretAvailable(@NonNull KeyStoreRecoveryMetadata recoverySecret, int userId) throws RemoteException { @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.recoverySecretAvailable(recoverySecret, userId); } Loading @@ -1995,14 +1999,14 @@ public class LockSettingsService extends ILockSettings.Stub { public byte[] startRecoverySession(@NonNull String sessionId, @NonNull byte[] verifierPublicKey, @NonNull byte[] vaultParams, @NonNull byte[] vaultChallenge, @NonNull List<KeyStoreRecoveryMetadata> secrets, int userId) throws RemoteException { @UserIdInt int userId) throws RemoteException { return mRecoverableKeyStoreManager.startRecoverySession(sessionId, verifierPublicKey, vaultParams, vaultChallenge, secrets, userId); } @Override public void recoverKeys(@NonNull String sessionId, @NonNull byte[] recoveryKeyBlob, @NonNull List<KeyEntryRecoveryData> applicationKeys, int userId) @NonNull List<KeyEntryRecoveryData> applicationKeys, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.recoverKeys(sessionId, recoveryKeyBlob, applicationKeys, userId); Loading services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +33 −7 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.security.recoverablekeystore.KeyStoreRecoveryMetadata; import android.security.recoverablekeystore.RecoverableKeyStoreLoader; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.LockPatternUtils; import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb; import com.android.server.locksettings.recoverablekeystore.storage.RecoverySessionStorage; Loading @@ -50,7 +51,6 @@ import java.util.Map; */ public class RecoverableKeyStoreManager { private static final String TAG = "RecoverableKeyStoreManager"; private static RecoverableKeyStoreManager mInstance; private final Context mContext; Loading Loading @@ -278,23 +278,49 @@ public class RecoverableKeyStoreManager { throw new UnsupportedOperationException(); } /** 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. Password length should be at most 16 symbols {@code * mPasswordMaxLength} * @param userId for user who just unlocked the device. * @hide */ public void lockScreenSecretAvailable( @KeyStoreRecoveryMetadata.LockScreenUiFormat int type, String unencryptedPassword, int userId) { int storedHashType, @NonNull String credential, int userId) { // Notify RecoverableKeystoreLoader about unlock @KeyStoreRecoveryMetadata.LockScreenUiFormat int uiFormat; if (storedHashType == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) { uiFormat = KeyStoreRecoveryMetadata.TYPE_PATTERN; } else if (isPin(credential)) { uiFormat = KeyStoreRecoveryMetadata.TYPE_PIN; } else { uiFormat = KeyStoreRecoveryMetadata.TYPE_PASSWORD; } // TODO: check getPendingRecoverySecretTypes. // TODO: compute SHA256 or Argon2id depending on secret type. throw new UnsupportedOperationException(); } /** This function can only be used inside LockSettingsService. */ public void lockScreenSecretChanged( @KeyStoreRecoveryMetadata.LockScreenUiFormat int type, @Nullable String unencryptedPassword, @Nullable String credential, int userId) { throw new UnsupportedOperationException(); } @VisibleForTesting boolean isPin(@NonNull String credential) { for (int i = 0; i < credential.length(); i++) { char c = credential.charAt(i); if (c < '0' || c > '9') { return false; } } return true; } private void checkRecoverKeyStorePermission() { mContext.enforceCallingOrSelfPermission( RecoverableKeyStoreLoader.PERMISSION_RECOVER_KEYSTORE, Loading Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +15 −11 Original line number Diff line number Diff line Loading @@ -1741,6 +1741,10 @@ public class LockSettingsService extends ILockSettings.Stub { } } } // Use credentials to create recoverable keystore snapshot. mRecoverableKeyStoreManager.lockScreenSecretAvailable(storedHash.type, credential, userId); } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { if (response.getTimeout() > 0) { requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId); Loading Loading @@ -1931,14 +1935,14 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void initRecoveryService(@NonNull String rootCertificateAlias, @NonNull byte[] signedPublicKeyList, int userId) @NonNull byte[] signedPublicKeyList, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.initRecoveryService(rootCertificateAlias, signedPublicKeyList, userId); } @Override public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account, int userId) public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account, @UserIdInt int userId) throws RemoteException { return mRecoverableKeyStoreManager.getRecoveryData(account, userId); } Loading @@ -1953,13 +1957,14 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override public void setServerParameters(long serverParameters, int userId) throws RemoteException { public void setServerParameters(long serverParameters, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.setServerParameters(serverParameters, userId); } @Override public void setRecoveryStatus(@NonNull String packageName, @Nullable String[] aliases, int status, int userId) throws RemoteException { int status, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.setRecoveryStatus(packageName, aliases, status, userId); } Loading @@ -1969,25 +1974,24 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void setRecoverySecretTypes(@NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] secretTypes, int userId) throws RemoteException { int[] secretTypes, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.setRecoverySecretTypes(secretTypes, userId); } @Override public int[] getRecoverySecretTypes(int userId) throws RemoteException { public int[] getRecoverySecretTypes(@UserIdInt int userId) throws RemoteException { return mRecoverableKeyStoreManager.getRecoverySecretTypes(userId); } @Override public int[] getPendingRecoverySecretTypes(int userId) throws RemoteException { public int[] getPendingRecoverySecretTypes(@UserIdInt int userId) throws RemoteException { throw new SecurityException("Not implemented"); } @Override public void recoverySecretAvailable(@NonNull KeyStoreRecoveryMetadata recoverySecret, int userId) throws RemoteException { @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.recoverySecretAvailable(recoverySecret, userId); } Loading @@ -1995,14 +1999,14 @@ public class LockSettingsService extends ILockSettings.Stub { public byte[] startRecoverySession(@NonNull String sessionId, @NonNull byte[] verifierPublicKey, @NonNull byte[] vaultParams, @NonNull byte[] vaultChallenge, @NonNull List<KeyStoreRecoveryMetadata> secrets, int userId) throws RemoteException { @UserIdInt int userId) throws RemoteException { return mRecoverableKeyStoreManager.startRecoverySession(sessionId, verifierPublicKey, vaultParams, vaultChallenge, secrets, userId); } @Override public void recoverKeys(@NonNull String sessionId, @NonNull byte[] recoveryKeyBlob, @NonNull List<KeyEntryRecoveryData> applicationKeys, int userId) @NonNull List<KeyEntryRecoveryData> applicationKeys, @UserIdInt int userId) throws RemoteException { mRecoverableKeyStoreManager.recoverKeys(sessionId, recoveryKeyBlob, applicationKeys, userId); Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +33 −7 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.security.recoverablekeystore.KeyStoreRecoveryMetadata; import android.security.recoverablekeystore.RecoverableKeyStoreLoader; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.LockPatternUtils; import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb; import com.android.server.locksettings.recoverablekeystore.storage.RecoverySessionStorage; Loading @@ -50,7 +51,6 @@ import java.util.Map; */ public class RecoverableKeyStoreManager { private static final String TAG = "RecoverableKeyStoreManager"; private static RecoverableKeyStoreManager mInstance; private final Context mContext; Loading Loading @@ -278,23 +278,49 @@ public class RecoverableKeyStoreManager { throw new UnsupportedOperationException(); } /** 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. Password length should be at most 16 symbols {@code * mPasswordMaxLength} * @param userId for user who just unlocked the device. * @hide */ public void lockScreenSecretAvailable( @KeyStoreRecoveryMetadata.LockScreenUiFormat int type, String unencryptedPassword, int userId) { int storedHashType, @NonNull String credential, int userId) { // Notify RecoverableKeystoreLoader about unlock @KeyStoreRecoveryMetadata.LockScreenUiFormat int uiFormat; if (storedHashType == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) { uiFormat = KeyStoreRecoveryMetadata.TYPE_PATTERN; } else if (isPin(credential)) { uiFormat = KeyStoreRecoveryMetadata.TYPE_PIN; } else { uiFormat = KeyStoreRecoveryMetadata.TYPE_PASSWORD; } // TODO: check getPendingRecoverySecretTypes. // TODO: compute SHA256 or Argon2id depending on secret type. throw new UnsupportedOperationException(); } /** This function can only be used inside LockSettingsService. */ public void lockScreenSecretChanged( @KeyStoreRecoveryMetadata.LockScreenUiFormat int type, @Nullable String unencryptedPassword, @Nullable String credential, int userId) { throw new UnsupportedOperationException(); } @VisibleForTesting boolean isPin(@NonNull String credential) { for (int i = 0; i < credential.length(); i++) { char c = credential.charAt(i); if (c < '0' || c > '9') { return false; } } return true; } private void checkRecoverKeyStorePermission() { mContext.enforceCallingOrSelfPermission( RecoverableKeyStoreLoader.PERMISSION_RECOVER_KEYSTORE, Loading