Loading core/java/android/app/admin/PasswordMetrics.java +26 −19 Original line number Diff line number Diff line Loading @@ -73,6 +73,11 @@ public final class PasswordMetrics implements Parcelable { // consider it a complex PIN/password. public static final int MAX_ALLOWED_SEQUENCE = 3; // One of CREDENTIAL_TYPE_NONE, CREDENTIAL_TYPE_PATTERN or CREDENTIAL_TYPE_PASSWORD. // Note that this class still uses CREDENTIAL_TYPE_PASSWORD to represent both numeric PIN // and alphabetic password. This is OK as long as this definition is only used internally, // and the value never gets mixed up with credential types from other parts of the framework. // TODO: fix this (ideally after we move logic to PasswordPolicy) public @CredentialType int credType; // Fields below only make sense when credType is PASSWORD. public int length = 0; Loading Loading @@ -161,6 +166,7 @@ public final class PasswordMetrics implements Parcelable { public static final @NonNull Parcelable.Creator<PasswordMetrics> CREATOR = new Parcelable.Creator<PasswordMetrics>() { @Override public PasswordMetrics createFromParcel(Parcel in) { int credType = in.readInt(); int length = in.readInt(); Loading @@ -172,10 +178,11 @@ public final class PasswordMetrics implements Parcelable { int nonLetter = in.readInt(); int nonNumeric = in.readInt(); int seqLength = in.readInt(); return new PasswordMetrics(credType, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter, nonNumeric, seqLength); return new PasswordMetrics(credType, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter, nonNumeric, seqLength); } @Override public PasswordMetrics[] newArray(int size) { return new PasswordMetrics[size]; } Loading @@ -189,7 +196,7 @@ public final class PasswordMetrics implements Parcelable { * {@link com.android.internal.widget.LockPatternUtils#CREDENTIAL_TYPE_PASSWORD}. */ public static PasswordMetrics computeForCredential(LockscreenCredential credential) { if (credential.isPassword()) { if (credential.isPassword() || credential.isPin()) { return PasswordMetrics.computeForPassword(credential.getCredential()); } else if (credential.isPattern()) { return new PasswordMetrics(CREDENTIAL_TYPE_PATTERN); Loading core/java/com/android/internal/widget/ILockSettings.aidl +8 −10 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.security.keystore.recovery.KeyChainSnapshot; import android.security.keystore.recovery.KeyChainProtectionParams; import android.security.keystore.recovery.RecoveryCertPath; import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.VerifyCredentialResponse; import java.util.Map; Loading @@ -42,19 +43,16 @@ interface ILockSettings { long getLong(in String key, in long defaultValue, in int userId); @UnsupportedAppUsage String getString(in String key, in String defaultValue, in int userId); boolean setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange); boolean setLockCredential(in LockscreenCredential credential, in LockscreenCredential savedCredential, int userId, boolean allowUntrustedChange); void resetKeyStore(int userId); VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId, VerifyCredentialResponse checkCredential(in LockscreenCredential credential, int userId, in ICheckCredentialProgressCallback progressCallback); VerifyCredentialResponse verifyCredential(in byte[] credential, int type, long challenge, int userId); VerifyCredentialResponse verifyTiedProfileChallenge(in byte[] credential, int type, long challenge, int userId); VerifyCredentialResponse verifyCredential(in LockscreenCredential credential, long challenge, int userId); VerifyCredentialResponse verifyTiedProfileChallenge(in LockscreenCredential credential, long challenge, int userId); boolean checkVoldPassword(int userId); @UnsupportedAppUsage boolean havePattern(int userId); @UnsupportedAppUsage boolean havePassword(int userId); byte[] getHashFactor(in byte[] currentCredential, int userId); void setSeparateProfileChallengeEnabled(int userId, boolean enabled, in byte[] managedUserPassword); int getCredentialType(int userId); byte[] getHashFactor(in LockscreenCredential currentCredential, int userId); void setSeparateProfileChallengeEnabled(int userId, boolean enabled, in LockscreenCredential managedUserPassword); boolean getSeparateProfileChallengeEnabled(int userId); void registerStrongAuthTracker(in IStrongAuthTracker tracker); void unregisterStrongAuthTracker(in IStrongAuthTracker tracker); Loading core/java/com/android/internal/widget/LockPatternUtils.java +72 −102 Original line number Diff line number Diff line Loading @@ -17,9 +17,6 @@ package com.android.internal.widget; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; Loading Loading @@ -59,10 +56,10 @@ import android.util.SparseLongArray; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import libcore.util.HexEncoding; import com.google.android.collect.Lists; import libcore.util.HexEncoding; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.MessageDigest; Loading Loading @@ -117,13 +114,19 @@ public class LockPatternUtils { // NOTE: When modifying this, make sure credential sufficiency validation logic is intact. public static final int CREDENTIAL_TYPE_NONE = -1; public static final int CREDENTIAL_TYPE_PATTERN = 1; public static final int CREDENTIAL_TYPE_PASSWORD = 2; // This is the legacy value persisted on disk. Never return it to clients, but internally // we still need it to handle upgrade cases. public static final int CREDENTIAL_TYPE_PASSWORD_OR_PIN = 2; public static final int CREDENTIAL_TYPE_PIN = 3; public static final int CREDENTIAL_TYPE_PASSWORD = 4; @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"CREDENTIAL_TYPE_"}, value = { CREDENTIAL_TYPE_NONE, CREDENTIAL_TYPE_PATTERN, CREDENTIAL_TYPE_PASSWORD, // Either pin or password. CREDENTIAL_TYPE_PASSWORD, CREDENTIAL_TYPE_PIN, // CREDENTIAL_TYPE_PASSWORD_OR_PIN is missing on purpose. }) public @interface CredentialType {} Loading Loading @@ -169,6 +172,7 @@ public class LockPatternUtils { public static final String SYNTHETIC_PASSWORD_HANDLE_KEY = "sp-handle"; public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp"; public static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1; private static final String HISTORY_DELIMITER = ","; @UnsupportedAppUsage Loading Loading @@ -372,8 +376,8 @@ public class LockPatternUtils { * * @param credential The credential to check. * @param challenge The challenge to verify against the credential * @return the attestation that the challenge was verified, or null * @param userId The user whose credential is being verified * @return the attestation that the challenge was verified, or null * @throws RequestThrottledException if credential verification is being throttled due to * to many incorrect attempts. * @throws IllegalStateException if called on the main thread. Loading @@ -383,7 +387,7 @@ public class LockPatternUtils { throwIfCalledOnMainThread(); try { VerifyCredentialResponse response = getLockSettings().verifyCredential( credential.getCredential(), credential.getType(), challenge, userId); credential, challenge, userId); if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { return response.getPayload(); } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { Loading @@ -392,6 +396,7 @@ public class LockPatternUtils { return null; } } catch (RemoteException re) { Log.e(TAG, "failed to verify credential", re); return null; } } Loading @@ -413,8 +418,7 @@ public class LockPatternUtils { throwIfCalledOnMainThread(); try { VerifyCredentialResponse response = getLockSettings().checkCredential( credential.getCredential(), credential.getType(), userId, wrapCallback(progressCallback)); credential, userId, wrapCallback(progressCallback)); if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { return true; Loading @@ -424,6 +428,7 @@ public class LockPatternUtils { return false; } } catch (RemoteException re) { Log.e(TAG, "failed to check credential", re); return false; } } Loading @@ -447,8 +452,7 @@ public class LockPatternUtils { throwIfCalledOnMainThread(); try { VerifyCredentialResponse response = getLockSettings().verifyTiedProfileChallenge( credential.getCredential(), credential.getType(), challenge, userId); getLockSettings().verifyTiedProfileChallenge(credential, challenge, userId); if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { return response.getPayload(); Loading @@ -458,6 +462,7 @@ public class LockPatternUtils { return null; } } catch (RemoteException re) { Log.e(TAG, "failed to verify tied profile credential", re); return null; } } Loading @@ -471,6 +476,7 @@ public class LockPatternUtils { try { return getLockSettings().checkVoldPassword(userId); } catch (RemoteException re) { Log.e(TAG, "failed to check vold password", re); return false; } } Loading @@ -482,7 +488,7 @@ public class LockPatternUtils { public byte[] getPasswordHistoryHashFactor(@NonNull LockscreenCredential currentPassword, int userId) { try { return getLockSettings().getHashFactor(currentPassword.getCredential(), userId); return getLockSettings().getHashFactor(currentPassword, userId); } catch (RemoteException e) { Log.e(TAG, "failed to get hash factor", e); return null; Loading Loading @@ -523,30 +529,6 @@ public class LockPatternUtils { return false; } /** * Check to see if the user has stored a lock pattern. * @return Whether a saved pattern exists. */ private boolean savedPatternExists(int userId) { try { return getLockSettings().havePattern(userId); } catch (RemoteException re) { return false; } } /** * Check to see if the user has stored a lock pattern. * @return Whether a saved pattern exists. */ private boolean savedPasswordExists(int userId) { try { return getLockSettings().havePassword(userId); } catch (RemoteException re) { return false; } } /** * Return true if the user has ever chosen a pattern. This is true even if the pattern is * currently cleared. Loading @@ -568,22 +550,11 @@ public class LockPatternUtils { /** * Used by device policy manager to validate the current password * information it has. * @Deprecated use {@link #getKeyguardStoredPasswordQuality} */ @UnsupportedAppUsage public int getActivePasswordQuality(int userId) { int quality = getKeyguardStoredPasswordQuality(userId); if (isLockPasswordEnabled(quality, userId)) { // Quality is a password and a password exists. Return the quality. return quality; } if (isLockPatternEnabled(quality, userId)) { // Quality is a pattern and a pattern exists. Return the quality. return quality; } return PASSWORD_QUALITY_UNSPECIFIED; return getKeyguardStoredPasswordQuality(userId); } /** Loading Loading @@ -641,6 +612,22 @@ public class LockPatternUtils { return quality == PASSWORD_QUALITY_NUMERIC || quality == PASSWORD_QUALITY_NUMERIC_COMPLEX; } /** Returns the canonical password quality corresponding to the given credential type. */ public static int credentialTypeToPasswordQuality(int credentialType) { switch (credentialType) { case CREDENTIAL_TYPE_NONE: return PASSWORD_QUALITY_UNSPECIFIED; case CREDENTIAL_TYPE_PATTERN: return PASSWORD_QUALITY_SOMETHING; case CREDENTIAL_TYPE_PIN: return PASSWORD_QUALITY_NUMERIC; case CREDENTIAL_TYPE_PASSWORD: return PASSWORD_QUALITY_ALPHABETIC; default: throw new IllegalStateException("Unknown type: " + credentialType); } } /** * Save a new lockscreen credential. * Loading Loading @@ -684,19 +671,12 @@ public class LockPatternUtils { } newCredential.checkLength(); final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); setKeyguardStoredPasswordQuality(newCredential.getQuality(), userHandle); try { if (!getLockSettings().setLockCredential( newCredential.getCredential(), newCredential.getType(), savedCredential.getCredential(), newCredential.getQuality(), userHandle, allowUntrustedChange)) { setKeyguardStoredPasswordQuality(currentQuality, userHandle); newCredential, savedCredential, userHandle, allowUntrustedChange)) { return false; } } catch (RemoteException | RuntimeException e) { setKeyguardStoredPasswordQuality(currentQuality, userHandle); } catch (RemoteException e) { throw new RuntimeException("Unable to save lock password", e); } Loading Loading @@ -904,14 +884,12 @@ public class LockPatternUtils { * @see DevicePolicyManager#getPasswordQuality(android.content.ComponentName) * * @return stored password quality * @deprecated use {@link #getCredentialTypeForUser(int)} instead */ @UnsupportedAppUsage @Deprecated public int getKeyguardStoredPasswordQuality(int userHandle) { return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle); } private void setKeyguardStoredPasswordQuality(int quality, int userHandle) { setLong(PASSWORD_TYPE_KEY, quality, userHandle); return credentialTypeToPasswordQuality(getCredentialTypeForUser(userHandle)); } /** Loading @@ -920,17 +898,17 @@ public class LockPatternUtils { * * @param userHandle Managed profile user id * @param enabled True if separate challenge is enabled * @param managedUserPassword Managed profile previous password. Null when {@code enabled} is * @param profilePassword Managed profile previous password. Null when {@code enabled} is * true */ public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled, LockscreenCredential managedUserPassword) { LockscreenCredential profilePassword) { if (!isManagedProfile(userHandle)) { return; } try { getLockSettings().setSeparateProfileChallengeEnabled(userHandle, enabled, managedUserPassword.getCredential()); profilePassword); reportEnabledTrustAgentsChanged(userHandle); } catch (RemoteException e) { Log.e(TAG, "Couldn't update work profile challenge enabled"); Loading Loading @@ -1097,29 +1075,34 @@ public class LockPatternUtils { } } /** * Returns the credential type of the user, can be one of {@link #CREDENTIAL_TYPE_NONE}, * {@link #CREDENTIAL_TYPE_PATTERN}, {@link #CREDENTIAL_TYPE_PIN} and * {@link #CREDENTIAL_TYPE_PASSWORD} */ public @CredentialType int getCredentialTypeForUser(int userHandle) { try { return getLockSettings().getCredentialType(userHandle); } catch (RemoteException re) { Log.e(TAG, "failed to get credential type", re); return CREDENTIAL_TYPE_NONE; } } /** * @param userId the user for which to report the value * @return Whether the lock screen is secured. */ @UnsupportedAppUsage public boolean isSecure(int userId) { int mode = getKeyguardStoredPasswordQuality(userId); return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId); int type = getCredentialTypeForUser(userId); return type != CREDENTIAL_TYPE_NONE; } @UnsupportedAppUsage public boolean isLockPasswordEnabled(int userId) { return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId); } private boolean isLockPasswordEnabled(int mode, int userId) { final boolean passwordEnabled = mode == PASSWORD_QUALITY_ALPHABETIC || mode == PASSWORD_QUALITY_NUMERIC || mode == PASSWORD_QUALITY_NUMERIC_COMPLEX || mode == PASSWORD_QUALITY_ALPHANUMERIC || mode == PASSWORD_QUALITY_COMPLEX || mode == PASSWORD_QUALITY_MANAGED; return passwordEnabled && savedPasswordExists(userId); int type = getCredentialTypeForUser(userId); return type == CREDENTIAL_TYPE_PASSWORD || type == CREDENTIAL_TYPE_PIN; } /** Loading @@ -1127,7 +1110,8 @@ public class LockPatternUtils { */ @UnsupportedAppUsage public boolean isLockPatternEnabled(int userId) { return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId); int type = getCredentialTypeForUser(userId); return type == CREDENTIAL_TYPE_PATTERN; } @Deprecated Loading @@ -1143,10 +1127,6 @@ public class LockPatternUtils { setBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, true, userId); } private boolean isLockPatternEnabled(int mode, int userId) { return mode == PASSWORD_QUALITY_SOMETHING && savedPatternExists(userId); } /** * @return Whether the visible pattern is enabled. */ Loading Loading @@ -1543,8 +1523,8 @@ public class LockPatternUtils { * @param userHandle The user who's lock credential to be changed * @return {@code true} if the operation is successful. */ public boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle, byte[] token, int userHandle) { public boolean setLockCredentialWithToken(@NonNull LockscreenCredential credential, long tokenHandle, byte[] token, int userHandle) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); Loading @@ -1552,20 +1532,9 @@ public class LockPatternUtils { credential.checkLength(); LockSettingsInternal localService = getLockSettingsInternal(); final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); setKeyguardStoredPasswordQuality(credential.getQuality(), userHandle); try { if (!localService.setLockCredentialWithToken(credential.getCredential(), credential.getType(), tokenHandle, token, credential.getQuality(), userHandle)) { setKeyguardStoredPasswordQuality(currentQuality, userHandle); if (!localService.setLockCredentialWithToken(credential, tokenHandle, token, userHandle)) { return false; } } catch (RuntimeException e) { setKeyguardStoredPasswordQuality(currentQuality, userHandle); throw new RuntimeException("Unable to save lock credential", e); } onPostPasswordChanged(credential, userHandle); return true; Loading Loading @@ -1765,7 +1734,8 @@ public class LockPatternUtils { } public boolean isSyntheticPasswordEnabled() { return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM) != 0; return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM) != 0; } /** Loading core/java/com/android/internal/widget/LockSettingsInternal.java +2 −2 Original line number Diff line number Diff line Loading @@ -59,8 +59,8 @@ public abstract class LockSettingsInternal { * * @return true if password is set. */ public abstract boolean setLockCredentialWithToken(byte[] credential, int type, long tokenHandle, byte[] token, int requestedQuality, int userId); public abstract boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle, byte[] token, int userId); public abstract boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId); Loading core/java/com/android/internal/widget/LockscreenCredential.aidl 0 → 100644 +23 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.widget; /** * A class representing a lockscreen credential. */ parcelable LockscreenCredential; Loading
core/java/android/app/admin/PasswordMetrics.java +26 −19 Original line number Diff line number Diff line Loading @@ -73,6 +73,11 @@ public final class PasswordMetrics implements Parcelable { // consider it a complex PIN/password. public static final int MAX_ALLOWED_SEQUENCE = 3; // One of CREDENTIAL_TYPE_NONE, CREDENTIAL_TYPE_PATTERN or CREDENTIAL_TYPE_PASSWORD. // Note that this class still uses CREDENTIAL_TYPE_PASSWORD to represent both numeric PIN // and alphabetic password. This is OK as long as this definition is only used internally, // and the value never gets mixed up with credential types from other parts of the framework. // TODO: fix this (ideally after we move logic to PasswordPolicy) public @CredentialType int credType; // Fields below only make sense when credType is PASSWORD. public int length = 0; Loading Loading @@ -161,6 +166,7 @@ public final class PasswordMetrics implements Parcelable { public static final @NonNull Parcelable.Creator<PasswordMetrics> CREATOR = new Parcelable.Creator<PasswordMetrics>() { @Override public PasswordMetrics createFromParcel(Parcel in) { int credType = in.readInt(); int length = in.readInt(); Loading @@ -172,10 +178,11 @@ public final class PasswordMetrics implements Parcelable { int nonLetter = in.readInt(); int nonNumeric = in.readInt(); int seqLength = in.readInt(); return new PasswordMetrics(credType, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter, nonNumeric, seqLength); return new PasswordMetrics(credType, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter, nonNumeric, seqLength); } @Override public PasswordMetrics[] newArray(int size) { return new PasswordMetrics[size]; } Loading @@ -189,7 +196,7 @@ public final class PasswordMetrics implements Parcelable { * {@link com.android.internal.widget.LockPatternUtils#CREDENTIAL_TYPE_PASSWORD}. */ public static PasswordMetrics computeForCredential(LockscreenCredential credential) { if (credential.isPassword()) { if (credential.isPassword() || credential.isPin()) { return PasswordMetrics.computeForPassword(credential.getCredential()); } else if (credential.isPattern()) { return new PasswordMetrics(CREDENTIAL_TYPE_PATTERN); Loading
core/java/com/android/internal/widget/ILockSettings.aidl +8 −10 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.security.keystore.recovery.KeyChainSnapshot; import android.security.keystore.recovery.KeyChainProtectionParams; import android.security.keystore.recovery.RecoveryCertPath; import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.VerifyCredentialResponse; import java.util.Map; Loading @@ -42,19 +43,16 @@ interface ILockSettings { long getLong(in String key, in long defaultValue, in int userId); @UnsupportedAppUsage String getString(in String key, in String defaultValue, in int userId); boolean setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange); boolean setLockCredential(in LockscreenCredential credential, in LockscreenCredential savedCredential, int userId, boolean allowUntrustedChange); void resetKeyStore(int userId); VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId, VerifyCredentialResponse checkCredential(in LockscreenCredential credential, int userId, in ICheckCredentialProgressCallback progressCallback); VerifyCredentialResponse verifyCredential(in byte[] credential, int type, long challenge, int userId); VerifyCredentialResponse verifyTiedProfileChallenge(in byte[] credential, int type, long challenge, int userId); VerifyCredentialResponse verifyCredential(in LockscreenCredential credential, long challenge, int userId); VerifyCredentialResponse verifyTiedProfileChallenge(in LockscreenCredential credential, long challenge, int userId); boolean checkVoldPassword(int userId); @UnsupportedAppUsage boolean havePattern(int userId); @UnsupportedAppUsage boolean havePassword(int userId); byte[] getHashFactor(in byte[] currentCredential, int userId); void setSeparateProfileChallengeEnabled(int userId, boolean enabled, in byte[] managedUserPassword); int getCredentialType(int userId); byte[] getHashFactor(in LockscreenCredential currentCredential, int userId); void setSeparateProfileChallengeEnabled(int userId, boolean enabled, in LockscreenCredential managedUserPassword); boolean getSeparateProfileChallengeEnabled(int userId); void registerStrongAuthTracker(in IStrongAuthTracker tracker); void unregisterStrongAuthTracker(in IStrongAuthTracker tracker); Loading
core/java/com/android/internal/widget/LockPatternUtils.java +72 −102 Original line number Diff line number Diff line Loading @@ -17,9 +17,6 @@ package com.android.internal.widget; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; Loading Loading @@ -59,10 +56,10 @@ import android.util.SparseLongArray; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import libcore.util.HexEncoding; import com.google.android.collect.Lists; import libcore.util.HexEncoding; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.MessageDigest; Loading Loading @@ -117,13 +114,19 @@ public class LockPatternUtils { // NOTE: When modifying this, make sure credential sufficiency validation logic is intact. public static final int CREDENTIAL_TYPE_NONE = -1; public static final int CREDENTIAL_TYPE_PATTERN = 1; public static final int CREDENTIAL_TYPE_PASSWORD = 2; // This is the legacy value persisted on disk. Never return it to clients, but internally // we still need it to handle upgrade cases. public static final int CREDENTIAL_TYPE_PASSWORD_OR_PIN = 2; public static final int CREDENTIAL_TYPE_PIN = 3; public static final int CREDENTIAL_TYPE_PASSWORD = 4; @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"CREDENTIAL_TYPE_"}, value = { CREDENTIAL_TYPE_NONE, CREDENTIAL_TYPE_PATTERN, CREDENTIAL_TYPE_PASSWORD, // Either pin or password. CREDENTIAL_TYPE_PASSWORD, CREDENTIAL_TYPE_PIN, // CREDENTIAL_TYPE_PASSWORD_OR_PIN is missing on purpose. }) public @interface CredentialType {} Loading Loading @@ -169,6 +172,7 @@ public class LockPatternUtils { public static final String SYNTHETIC_PASSWORD_HANDLE_KEY = "sp-handle"; public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp"; public static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1; private static final String HISTORY_DELIMITER = ","; @UnsupportedAppUsage Loading Loading @@ -372,8 +376,8 @@ public class LockPatternUtils { * * @param credential The credential to check. * @param challenge The challenge to verify against the credential * @return the attestation that the challenge was verified, or null * @param userId The user whose credential is being verified * @return the attestation that the challenge was verified, or null * @throws RequestThrottledException if credential verification is being throttled due to * to many incorrect attempts. * @throws IllegalStateException if called on the main thread. Loading @@ -383,7 +387,7 @@ public class LockPatternUtils { throwIfCalledOnMainThread(); try { VerifyCredentialResponse response = getLockSettings().verifyCredential( credential.getCredential(), credential.getType(), challenge, userId); credential, challenge, userId); if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { return response.getPayload(); } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { Loading @@ -392,6 +396,7 @@ public class LockPatternUtils { return null; } } catch (RemoteException re) { Log.e(TAG, "failed to verify credential", re); return null; } } Loading @@ -413,8 +418,7 @@ public class LockPatternUtils { throwIfCalledOnMainThread(); try { VerifyCredentialResponse response = getLockSettings().checkCredential( credential.getCredential(), credential.getType(), userId, wrapCallback(progressCallback)); credential, userId, wrapCallback(progressCallback)); if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { return true; Loading @@ -424,6 +428,7 @@ public class LockPatternUtils { return false; } } catch (RemoteException re) { Log.e(TAG, "failed to check credential", re); return false; } } Loading @@ -447,8 +452,7 @@ public class LockPatternUtils { throwIfCalledOnMainThread(); try { VerifyCredentialResponse response = getLockSettings().verifyTiedProfileChallenge( credential.getCredential(), credential.getType(), challenge, userId); getLockSettings().verifyTiedProfileChallenge(credential, challenge, userId); if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { return response.getPayload(); Loading @@ -458,6 +462,7 @@ public class LockPatternUtils { return null; } } catch (RemoteException re) { Log.e(TAG, "failed to verify tied profile credential", re); return null; } } Loading @@ -471,6 +476,7 @@ public class LockPatternUtils { try { return getLockSettings().checkVoldPassword(userId); } catch (RemoteException re) { Log.e(TAG, "failed to check vold password", re); return false; } } Loading @@ -482,7 +488,7 @@ public class LockPatternUtils { public byte[] getPasswordHistoryHashFactor(@NonNull LockscreenCredential currentPassword, int userId) { try { return getLockSettings().getHashFactor(currentPassword.getCredential(), userId); return getLockSettings().getHashFactor(currentPassword, userId); } catch (RemoteException e) { Log.e(TAG, "failed to get hash factor", e); return null; Loading Loading @@ -523,30 +529,6 @@ public class LockPatternUtils { return false; } /** * Check to see if the user has stored a lock pattern. * @return Whether a saved pattern exists. */ private boolean savedPatternExists(int userId) { try { return getLockSettings().havePattern(userId); } catch (RemoteException re) { return false; } } /** * Check to see if the user has stored a lock pattern. * @return Whether a saved pattern exists. */ private boolean savedPasswordExists(int userId) { try { return getLockSettings().havePassword(userId); } catch (RemoteException re) { return false; } } /** * Return true if the user has ever chosen a pattern. This is true even if the pattern is * currently cleared. Loading @@ -568,22 +550,11 @@ public class LockPatternUtils { /** * Used by device policy manager to validate the current password * information it has. * @Deprecated use {@link #getKeyguardStoredPasswordQuality} */ @UnsupportedAppUsage public int getActivePasswordQuality(int userId) { int quality = getKeyguardStoredPasswordQuality(userId); if (isLockPasswordEnabled(quality, userId)) { // Quality is a password and a password exists. Return the quality. return quality; } if (isLockPatternEnabled(quality, userId)) { // Quality is a pattern and a pattern exists. Return the quality. return quality; } return PASSWORD_QUALITY_UNSPECIFIED; return getKeyguardStoredPasswordQuality(userId); } /** Loading Loading @@ -641,6 +612,22 @@ public class LockPatternUtils { return quality == PASSWORD_QUALITY_NUMERIC || quality == PASSWORD_QUALITY_NUMERIC_COMPLEX; } /** Returns the canonical password quality corresponding to the given credential type. */ public static int credentialTypeToPasswordQuality(int credentialType) { switch (credentialType) { case CREDENTIAL_TYPE_NONE: return PASSWORD_QUALITY_UNSPECIFIED; case CREDENTIAL_TYPE_PATTERN: return PASSWORD_QUALITY_SOMETHING; case CREDENTIAL_TYPE_PIN: return PASSWORD_QUALITY_NUMERIC; case CREDENTIAL_TYPE_PASSWORD: return PASSWORD_QUALITY_ALPHABETIC; default: throw new IllegalStateException("Unknown type: " + credentialType); } } /** * Save a new lockscreen credential. * Loading Loading @@ -684,19 +671,12 @@ public class LockPatternUtils { } newCredential.checkLength(); final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); setKeyguardStoredPasswordQuality(newCredential.getQuality(), userHandle); try { if (!getLockSettings().setLockCredential( newCredential.getCredential(), newCredential.getType(), savedCredential.getCredential(), newCredential.getQuality(), userHandle, allowUntrustedChange)) { setKeyguardStoredPasswordQuality(currentQuality, userHandle); newCredential, savedCredential, userHandle, allowUntrustedChange)) { return false; } } catch (RemoteException | RuntimeException e) { setKeyguardStoredPasswordQuality(currentQuality, userHandle); } catch (RemoteException e) { throw new RuntimeException("Unable to save lock password", e); } Loading Loading @@ -904,14 +884,12 @@ public class LockPatternUtils { * @see DevicePolicyManager#getPasswordQuality(android.content.ComponentName) * * @return stored password quality * @deprecated use {@link #getCredentialTypeForUser(int)} instead */ @UnsupportedAppUsage @Deprecated public int getKeyguardStoredPasswordQuality(int userHandle) { return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle); } private void setKeyguardStoredPasswordQuality(int quality, int userHandle) { setLong(PASSWORD_TYPE_KEY, quality, userHandle); return credentialTypeToPasswordQuality(getCredentialTypeForUser(userHandle)); } /** Loading @@ -920,17 +898,17 @@ public class LockPatternUtils { * * @param userHandle Managed profile user id * @param enabled True if separate challenge is enabled * @param managedUserPassword Managed profile previous password. Null when {@code enabled} is * @param profilePassword Managed profile previous password. Null when {@code enabled} is * true */ public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled, LockscreenCredential managedUserPassword) { LockscreenCredential profilePassword) { if (!isManagedProfile(userHandle)) { return; } try { getLockSettings().setSeparateProfileChallengeEnabled(userHandle, enabled, managedUserPassword.getCredential()); profilePassword); reportEnabledTrustAgentsChanged(userHandle); } catch (RemoteException e) { Log.e(TAG, "Couldn't update work profile challenge enabled"); Loading Loading @@ -1097,29 +1075,34 @@ public class LockPatternUtils { } } /** * Returns the credential type of the user, can be one of {@link #CREDENTIAL_TYPE_NONE}, * {@link #CREDENTIAL_TYPE_PATTERN}, {@link #CREDENTIAL_TYPE_PIN} and * {@link #CREDENTIAL_TYPE_PASSWORD} */ public @CredentialType int getCredentialTypeForUser(int userHandle) { try { return getLockSettings().getCredentialType(userHandle); } catch (RemoteException re) { Log.e(TAG, "failed to get credential type", re); return CREDENTIAL_TYPE_NONE; } } /** * @param userId the user for which to report the value * @return Whether the lock screen is secured. */ @UnsupportedAppUsage public boolean isSecure(int userId) { int mode = getKeyguardStoredPasswordQuality(userId); return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId); int type = getCredentialTypeForUser(userId); return type != CREDENTIAL_TYPE_NONE; } @UnsupportedAppUsage public boolean isLockPasswordEnabled(int userId) { return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId); } private boolean isLockPasswordEnabled(int mode, int userId) { final boolean passwordEnabled = mode == PASSWORD_QUALITY_ALPHABETIC || mode == PASSWORD_QUALITY_NUMERIC || mode == PASSWORD_QUALITY_NUMERIC_COMPLEX || mode == PASSWORD_QUALITY_ALPHANUMERIC || mode == PASSWORD_QUALITY_COMPLEX || mode == PASSWORD_QUALITY_MANAGED; return passwordEnabled && savedPasswordExists(userId); int type = getCredentialTypeForUser(userId); return type == CREDENTIAL_TYPE_PASSWORD || type == CREDENTIAL_TYPE_PIN; } /** Loading @@ -1127,7 +1110,8 @@ public class LockPatternUtils { */ @UnsupportedAppUsage public boolean isLockPatternEnabled(int userId) { return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId); int type = getCredentialTypeForUser(userId); return type == CREDENTIAL_TYPE_PATTERN; } @Deprecated Loading @@ -1143,10 +1127,6 @@ public class LockPatternUtils { setBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, true, userId); } private boolean isLockPatternEnabled(int mode, int userId) { return mode == PASSWORD_QUALITY_SOMETHING && savedPatternExists(userId); } /** * @return Whether the visible pattern is enabled. */ Loading Loading @@ -1543,8 +1523,8 @@ public class LockPatternUtils { * @param userHandle The user who's lock credential to be changed * @return {@code true} if the operation is successful. */ public boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle, byte[] token, int userHandle) { public boolean setLockCredentialWithToken(@NonNull LockscreenCredential credential, long tokenHandle, byte[] token, int userHandle) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); Loading @@ -1552,20 +1532,9 @@ public class LockPatternUtils { credential.checkLength(); LockSettingsInternal localService = getLockSettingsInternal(); final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); setKeyguardStoredPasswordQuality(credential.getQuality(), userHandle); try { if (!localService.setLockCredentialWithToken(credential.getCredential(), credential.getType(), tokenHandle, token, credential.getQuality(), userHandle)) { setKeyguardStoredPasswordQuality(currentQuality, userHandle); if (!localService.setLockCredentialWithToken(credential, tokenHandle, token, userHandle)) { return false; } } catch (RuntimeException e) { setKeyguardStoredPasswordQuality(currentQuality, userHandle); throw new RuntimeException("Unable to save lock credential", e); } onPostPasswordChanged(credential, userHandle); return true; Loading Loading @@ -1765,7 +1734,8 @@ public class LockPatternUtils { } public boolean isSyntheticPasswordEnabled() { return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM) != 0; return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM) != 0; } /** Loading
core/java/com/android/internal/widget/LockSettingsInternal.java +2 −2 Original line number Diff line number Diff line Loading @@ -59,8 +59,8 @@ public abstract class LockSettingsInternal { * * @return true if password is set. */ public abstract boolean setLockCredentialWithToken(byte[] credential, int type, long tokenHandle, byte[] token, int requestedQuality, int userId); public abstract boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle, byte[] token, int userId); public abstract boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId); Loading
core/java/com/android/internal/widget/LockscreenCredential.aidl 0 → 100644 +23 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.widget; /** * A class representing a lockscreen credential. */ parcelable LockscreenCredential;