Merge "Fix keyguard/Keystore storage issue" into klp-dev
This commit is contained in:
@@ -24,10 +24,10 @@ interface ILockSettings {
|
|||||||
boolean getBoolean(in String key, in boolean defaultValue, in int userId);
|
boolean getBoolean(in String key, in boolean defaultValue, in int userId);
|
||||||
long getLong(in String key, in long defaultValue, in int userId);
|
long getLong(in String key, in long defaultValue, in int userId);
|
||||||
String getString(in String key, in String defaultValue, in int userId);
|
String getString(in String key, in String defaultValue, in int userId);
|
||||||
void setLockPattern(in byte[] hash, int userId);
|
void setLockPattern(in String pattern, int userId);
|
||||||
boolean checkPattern(in byte[] hash, int userId);
|
boolean checkPattern(in String pattern, int userId);
|
||||||
void setLockPassword(in byte[] hash, int userId);
|
void setLockPassword(in String password, int userId);
|
||||||
boolean checkPassword(in byte[] hash, int userId);
|
boolean checkPassword(in String password, int userId);
|
||||||
boolean havePattern(int userId);
|
boolean havePattern(int userId);
|
||||||
boolean havePassword(int userId);
|
boolean havePassword(int userId);
|
||||||
void removeUser(int userId);
|
void removeUser(int userId);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import android.os.SystemClock;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.storage.IMountService;
|
import android.os.storage.IMountService;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.security.KeyStore;
|
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -292,11 +291,7 @@ public class LockPatternUtils {
|
|||||||
public boolean checkPattern(List<LockPatternView.Cell> pattern) {
|
public boolean checkPattern(List<LockPatternView.Cell> pattern) {
|
||||||
final int userId = getCurrentOrCallingUserId();
|
final int userId = getCurrentOrCallingUserId();
|
||||||
try {
|
try {
|
||||||
final boolean matched = getLockSettings().checkPattern(patternToHash(pattern), userId);
|
return getLockSettings().checkPattern(patternToString(pattern), userId);
|
||||||
if (matched && (userId == UserHandle.USER_OWNER)) {
|
|
||||||
KeyStore.getInstance().password(patternToString(pattern));
|
|
||||||
}
|
|
||||||
return matched;
|
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -311,12 +306,7 @@ public class LockPatternUtils {
|
|||||||
public boolean checkPassword(String password) {
|
public boolean checkPassword(String password) {
|
||||||
final int userId = getCurrentOrCallingUserId();
|
final int userId = getCurrentOrCallingUserId();
|
||||||
try {
|
try {
|
||||||
final boolean matched = getLockSettings().checkPassword(passwordToHash(password),
|
return getLockSettings().checkPassword(password, userId);
|
||||||
userId);
|
|
||||||
if (matched && (userId == UserHandle.USER_OWNER)) {
|
|
||||||
KeyStore.getInstance().password(password);
|
|
||||||
}
|
|
||||||
return matched;
|
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -505,14 +495,10 @@ public class LockPatternUtils {
|
|||||||
* @param isFallback Specifies if this is a fallback to biometric weak
|
* @param isFallback Specifies if this is a fallback to biometric weak
|
||||||
*/
|
*/
|
||||||
public void saveLockPattern(List<LockPatternView.Cell> pattern, boolean isFallback) {
|
public void saveLockPattern(List<LockPatternView.Cell> pattern, boolean isFallback) {
|
||||||
// Compute the hash
|
|
||||||
final byte[] hash = LockPatternUtils.patternToHash(pattern);
|
|
||||||
try {
|
try {
|
||||||
getLockSettings().setLockPattern(hash, getCurrentOrCallingUserId());
|
getLockSettings().setLockPattern(patternToString(pattern), getCurrentOrCallingUserId());
|
||||||
DevicePolicyManager dpm = getDevicePolicyManager();
|
DevicePolicyManager dpm = getDevicePolicyManager();
|
||||||
KeyStore keyStore = KeyStore.getInstance();
|
|
||||||
if (pattern != null) {
|
if (pattern != null) {
|
||||||
keyStore.password(patternToString(pattern));
|
|
||||||
setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
|
setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
|
||||||
if (!isFallback) {
|
if (!isFallback) {
|
||||||
deleteGallery();
|
deleteGallery();
|
||||||
@@ -528,9 +514,6 @@ public class LockPatternUtils {
|
|||||||
0, 0, 0, 0, 0, 0, 0, getCurrentOrCallingUserId());
|
0, 0, 0, 0, 0, 0, 0, getCurrentOrCallingUserId());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (keyStore.isEmpty()) {
|
|
||||||
keyStore.reset();
|
|
||||||
}
|
|
||||||
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0,
|
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0,
|
||||||
0, 0, 0, 0, 0, getCurrentOrCallingUserId());
|
0, 0, 0, 0, 0, getCurrentOrCallingUserId());
|
||||||
}
|
}
|
||||||
@@ -637,19 +620,13 @@ public class LockPatternUtils {
|
|||||||
* @param userHandle The userId of the user to change the password for
|
* @param userHandle The userId of the user to change the password for
|
||||||
*/
|
*/
|
||||||
public void saveLockPassword(String password, int quality, boolean isFallback, int userHandle) {
|
public void saveLockPassword(String password, int quality, boolean isFallback, int userHandle) {
|
||||||
// Compute the hash
|
|
||||||
final byte[] hash = passwordToHash(password);
|
|
||||||
try {
|
try {
|
||||||
getLockSettings().setLockPassword(hash, userHandle);
|
getLockSettings().setLockPassword(password, userHandle);
|
||||||
DevicePolicyManager dpm = getDevicePolicyManager();
|
DevicePolicyManager dpm = getDevicePolicyManager();
|
||||||
KeyStore keyStore = KeyStore.getInstance();
|
|
||||||
if (password != null) {
|
if (password != null) {
|
||||||
if (userHandle == UserHandle.USER_OWNER) {
|
if (userHandle == UserHandle.USER_OWNER) {
|
||||||
// Update the encryption password.
|
// Update the encryption password.
|
||||||
updateEncryptionPassword(password);
|
updateEncryptionPassword(password);
|
||||||
|
|
||||||
// Update the keystore password
|
|
||||||
keyStore.password(password);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int computedQuality = computePasswordQuality(password);
|
int computedQuality = computePasswordQuality(password);
|
||||||
@@ -709,6 +686,7 @@ public class LockPatternUtils {
|
|||||||
if (passwordHistoryLength == 0) {
|
if (passwordHistoryLength == 0) {
|
||||||
passwordHistory = "";
|
passwordHistory = "";
|
||||||
} else {
|
} else {
|
||||||
|
byte[] hash = passwordToHash(password);
|
||||||
passwordHistory = new String(hash) + "," + passwordHistory;
|
passwordHistory = new String(hash) + "," + passwordHistory;
|
||||||
// Cut it to contain passwordHistoryLength hashes
|
// Cut it to contain passwordHistoryLength hashes
|
||||||
// and passwordHistoryLength -1 commas.
|
// and passwordHistoryLength -1 commas.
|
||||||
@@ -718,11 +696,6 @@ public class LockPatternUtils {
|
|||||||
}
|
}
|
||||||
setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
|
setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
|
||||||
} else {
|
} else {
|
||||||
// Conditionally reset the keystore if empty. If
|
|
||||||
// non-empty, we are just switching key guard type
|
|
||||||
if (keyStore.isEmpty()) {
|
|
||||||
keyStore.reset();
|
|
||||||
}
|
|
||||||
dpm.setActivePasswordState(
|
dpm.setActivePasswordState(
|
||||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0,
|
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0,
|
||||||
userHandle);
|
userHandle);
|
||||||
@@ -803,7 +776,7 @@ public class LockPatternUtils {
|
|||||||
* @param pattern the gesture pattern.
|
* @param pattern the gesture pattern.
|
||||||
* @return the hash of the pattern in a byte array.
|
* @return the hash of the pattern in a byte array.
|
||||||
*/
|
*/
|
||||||
private static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
|
public static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
|
||||||
if (pattern == null) {
|
if (pattern == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import android.os.UserManager;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.Secure;
|
import android.provider.Settings.Secure;
|
||||||
import android.provider.Settings.SettingNotFoundException;
|
import android.provider.Settings.SettingNotFoundException;
|
||||||
|
import android.security.KeyStore;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -80,11 +81,14 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
private static final String LOCK_PASSWORD_FILE = "password.key";
|
private static final String LOCK_PASSWORD_FILE = "password.key";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
private LockPatternUtils mLockPatternUtils;
|
||||||
|
|
||||||
public LockSettingsService(Context context) {
|
public LockSettingsService(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
// Open the database
|
// Open the database
|
||||||
mOpenHelper = new DatabaseHelper(mContext);
|
mOpenHelper = new DatabaseHelper(mContext);
|
||||||
|
|
||||||
|
mLockPatternUtils = new LockPatternUtils(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void systemReady() {
|
public void systemReady() {
|
||||||
@@ -255,15 +259,42 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
return new File(getLockPatternFilename(userId)).length() > 0;
|
return new File(getLockPatternFilename(userId)).length() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maybeUpdateKeystore(String password, int userId) {
|
||||||
|
if (userId == UserHandle.USER_OWNER) {
|
||||||
|
final KeyStore keyStore = KeyStore.getInstance();
|
||||||
|
// Conditionally reset the keystore if empty. If non-empty, we are just
|
||||||
|
// switching key guard type
|
||||||
|
if (TextUtils.isEmpty(password) && keyStore.isEmpty()) {
|
||||||
|
keyStore.reset();
|
||||||
|
} else {
|
||||||
|
// Update the keystore password
|
||||||
|
keyStore.password(password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLockPattern(byte[] hash, int userId) throws RemoteException {
|
public void setLockPattern(String pattern, int userId) throws RemoteException {
|
||||||
checkWritePermission(userId);
|
checkWritePermission(userId);
|
||||||
|
|
||||||
|
maybeUpdateKeystore(pattern, userId);
|
||||||
|
|
||||||
|
final byte[] hash = LockPatternUtils.patternToHash(
|
||||||
|
LockPatternUtils.stringToPattern(pattern));
|
||||||
writeFile(getLockPatternFilename(userId), hash);
|
writeFile(getLockPatternFilename(userId), hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkPattern(byte[] hash, int userId) throws RemoteException {
|
public void setLockPassword(String password, int userId) throws RemoteException {
|
||||||
|
checkWritePermission(userId);
|
||||||
|
|
||||||
|
maybeUpdateKeystore(password, userId);
|
||||||
|
|
||||||
|
writeFile(getLockPasswordFilename(userId), mLockPatternUtils.passwordToHash(password));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkPattern(String pattern, int userId) throws RemoteException {
|
||||||
checkPasswordReadPermission(userId);
|
checkPasswordReadPermission(userId);
|
||||||
try {
|
try {
|
||||||
// Read all the bytes from the file
|
// Read all the bytes from the file
|
||||||
@@ -275,25 +306,23 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Compare the hash from the file with the entered pattern's hash
|
// Compare the hash from the file with the entered pattern's hash
|
||||||
return Arrays.equals(stored, hash);
|
final byte[] hash = LockPatternUtils.patternToHash(
|
||||||
|
LockPatternUtils.stringToPattern(pattern));
|
||||||
|
final boolean matched = Arrays.equals(stored, hash);
|
||||||
|
if (matched && !TextUtils.isEmpty(pattern)) {
|
||||||
|
maybeUpdateKeystore(pattern, userId);
|
||||||
|
}
|
||||||
|
return matched;
|
||||||
} catch (FileNotFoundException fnfe) {
|
} catch (FileNotFoundException fnfe) {
|
||||||
Slog.e(TAG, "Cannot read file " + fnfe);
|
Slog.e(TAG, "Cannot read file " + fnfe);
|
||||||
return true;
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Slog.e(TAG, "Cannot read file " + ioe);
|
Slog.e(TAG, "Cannot read file " + ioe);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLockPassword(byte[] hash, int userId) throws RemoteException {
|
public boolean checkPassword(String password, int userId) throws RemoteException {
|
||||||
checkWritePermission(userId);
|
|
||||||
|
|
||||||
writeFile(getLockPasswordFilename(userId), hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkPassword(byte[] hash, int userId) throws RemoteException {
|
|
||||||
checkPasswordReadPermission(userId);
|
checkPasswordReadPermission(userId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -306,14 +335,18 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Compare the hash from the file with the entered password's hash
|
// Compare the hash from the file with the entered password's hash
|
||||||
return Arrays.equals(stored, hash);
|
final byte[] hash = mLockPatternUtils.passwordToHash(password);
|
||||||
|
final boolean matched = Arrays.equals(stored, hash);
|
||||||
|
if (matched && !TextUtils.isEmpty(password)) {
|
||||||
|
maybeUpdateKeystore(password, userId);
|
||||||
|
}
|
||||||
|
return matched;
|
||||||
} catch (FileNotFoundException fnfe) {
|
} catch (FileNotFoundException fnfe) {
|
||||||
Slog.e(TAG, "Cannot read file " + fnfe);
|
Slog.e(TAG, "Cannot read file " + fnfe);
|
||||||
return true;
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Slog.e(TAG, "Cannot read file " + ioe);
|
Slog.e(TAG, "Cannot read file " + ioe);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -445,13 +478,12 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) {
|
private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) {
|
||||||
final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
|
final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
|
||||||
final ContentResolver cr = mContext.getContentResolver();
|
final ContentResolver cr = mContext.getContentResolver();
|
||||||
final LockPatternUtils utils = new LockPatternUtils(mContext);
|
|
||||||
final List<UserInfo> users = um.getUsers();
|
final List<UserInfo> users = um.getUsers();
|
||||||
for (int i = 0; i < users.size(); i++) {
|
for (int i = 0; i < users.size(); i++) {
|
||||||
final int userId = users.get(i).id;
|
final int userId = users.get(i).id;
|
||||||
final boolean enabled = utils.hasWidgetsEnabledInKeyguard(userId);
|
final boolean enabled = mLockPatternUtils.hasWidgetsEnabledInKeyguard(userId);
|
||||||
Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled="
|
Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled="
|
||||||
+ enabled + ", w[]=" + utils.getAppWidgets());
|
+ enabled + ", w[]=" + mLockPatternUtils.getAppWidgets());
|
||||||
loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled);
|
loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user