Refactor passwords/pins/patterns to byte[]

Relating to packages/apps/Settings

Bug: 120484642
Test: manual - test setting and unlocking passwords/pins/patterns.
      automated - 20 of about 500 tests fail due to fragile synthetic
      password test code.

Change-Id: Idec8338d141c185bef67ade12035fdb2fa9d17ea
This commit is contained in:
Rich Cannings
2019-02-19 13:15:30 -08:00
parent 3189d7b332
commit b27c4308a2
12 changed files with 116 additions and 80 deletions

View File

@@ -38,6 +38,7 @@ import android.widget.Button;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.InstrumentedFragment;
import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
public class CryptKeeperConfirm extends InstrumentedFragment { public class CryptKeeperConfirm extends InstrumentedFragment {
@@ -87,7 +88,12 @@ public class CryptKeeperConfirm extends InstrumentedFragment {
IStorageManager storageManager = IStorageManager.Stub.asInterface(service); IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
try { try {
Bundle args = getIntent().getExtras(); Bundle args = getIntent().getExtras();
storageManager.encryptStorage(args.getInt("type", -1), args.getString("password")); // TODO(b/120484642): Update vold to accept a password as a byte array
byte[] passwordBytes = args.getByteArray("password");
String password = passwordBytes != null ? new String(passwordBytes) : null;
Arrays.fill(passwordBytes, (byte) 0);
storageManager.encryptStorage(args.getInt("type", -1),
password);
} catch (Exception e) { } catch (Exception e) {
Log.e("CryptKeeper", "Error while encrypting...", e); Log.e("CryptKeeper", "Error while encrypting...", e);
} }

View File

@@ -76,6 +76,7 @@ import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.FooterPreferenceMixinCompat; import com.android.settingslib.widget.FooterPreferenceMixinCompat;
import java.util.Arrays;
import java.util.List; import java.util.List;
public class ChooseLockGeneric extends SettingsActivity { public class ChooseLockGeneric extends SettingsActivity {
@@ -151,7 +152,7 @@ public class ChooseLockGeneric extends SettingsActivity {
private boolean mPasswordConfirmed = false; private boolean mPasswordConfirmed = false;
private boolean mWaitingForConfirmation = false; private boolean mWaitingForConfirmation = false;
private boolean mForChangeCredRequiredForBoot = false; private boolean mForChangeCredRequiredForBoot = false;
private String mUserPassword; private byte[] mUserPassword;
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private FingerprintManager mFingerprintManager; private FingerprintManager mFingerprintManager;
private FaceManager mFaceManager; private FaceManager mFaceManager;
@@ -200,7 +201,7 @@ public class ChooseLockGeneric extends SettingsActivity {
.getBooleanExtra(CONFIRM_CREDENTIALS, true); .getBooleanExtra(CONFIRM_CREDENTIALS, true);
if (getActivity() instanceof ChooseLockGeneric.InternalActivity) { if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
mPasswordConfirmed = !confirmCredentials; mPasswordConfirmed = !confirmCredentials;
mUserPassword = getActivity().getIntent().getStringExtra( mUserPassword = getActivity().getIntent().getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
} }
@@ -224,7 +225,7 @@ public class ChooseLockGeneric extends SettingsActivity {
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED); mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION); mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
if (mUserPassword == null) { if (mUserPassword == null) {
mUserPassword = savedInstanceState.getString( mUserPassword = savedInstanceState.getByteArray(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
} }
} }
@@ -383,11 +384,11 @@ public class ChooseLockGeneric extends SettingsActivity {
if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) { if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) {
mPasswordConfirmed = true; mPasswordConfirmed = true;
mUserPassword = data != null mUserPassword = data != null
? data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD) ? data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)
: null; : null;
updatePreferencesOrFinish(false /* isRecreatingActivity */); updatePreferencesOrFinish(false /* isRecreatingActivity */);
if (mForChangeCredRequiredForBoot) { if (mForChangeCredRequiredForBoot) {
if (!TextUtils.isEmpty(mUserPassword)) { if (!(mUserPassword == null || mUserPassword.length == 0)) {
maybeEnableEncryption( maybeEnableEncryption(
mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId), false); mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId), false);
} else { } else {
@@ -447,7 +448,7 @@ public class ChooseLockGeneric extends SettingsActivity {
outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed); outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation); outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation);
if (mUserPassword != null) { if (mUserPassword != null) {
outState.putString(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mUserPassword); outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mUserPassword);
} }
} }
@@ -669,7 +670,7 @@ public class ChooseLockGeneric extends SettingsActivity {
setPreferenceSummary(ScreenLockType.MANAGED, R.string.secure_lock_encryption_warning); setPreferenceSummary(ScreenLockType.MANAGED, R.string.secure_lock_encryption_warning);
} }
protected Intent getLockManagedPasswordIntent(String password) { protected Intent getLockManagedPasswordIntent(byte[] password) {
return mManagedPasswordProvider.createIntent(false, password); return mManagedPasswordProvider.createIntent(false, password);
} }

View File

@@ -78,6 +78,7 @@ import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupdesign.GlifLayout; import com.google.android.setupdesign.GlifLayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
public class ChooseLockPassword extends SettingsActivity { public class ChooseLockPassword extends SettingsActivity {
@@ -123,7 +124,7 @@ public class ChooseLockPassword extends SettingsActivity {
return this; return this;
} }
public IntentBuilder setPassword(String password) { public IntentBuilder setPassword(byte[] password) {
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password); mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password);
return this; return this;
} }
@@ -185,8 +186,8 @@ public class ChooseLockPassword extends SettingsActivity {
private static final String KEY_CURRENT_PASSWORD = "current_password"; private static final String KEY_CURRENT_PASSWORD = "current_password";
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker"; private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
private String mCurrentPassword; private byte[] mCurrentPassword;
private String mChosenPassword; private byte[] mChosenPassword;
private boolean mHasChallenge; private boolean mHasChallenge;
private long mChallenge; private long mChallenge;
private ImeAwareEditText mPasswordEntry; private ImeAwareEditText mPasswordEntry;
@@ -215,7 +216,7 @@ public class ChooseLockPassword extends SettingsActivity {
protected boolean mForFingerprint; protected boolean mForFingerprint;
protected boolean mForFace; protected boolean mForFace;
private String mFirstPin; private byte[] mFirstPin;
private RecyclerView mPasswordRestrictionView; private RecyclerView mPasswordRestrictionView;
protected boolean mIsAlphaMode; protected boolean mIsAlphaMode;
protected FooterButton mSkipOrClearButton; protected FooterButton mSkipOrClearButton;
@@ -234,7 +235,7 @@ public class ChooseLockPassword extends SettingsActivity {
private static final int MIN_NUMBER_IN_PASSWORD = 4; private static final int MIN_NUMBER_IN_PASSWORD = 4;
private static final int MIN_NON_LETTER_IN_PASSWORD = 5; private static final int MIN_NON_LETTER_IN_PASSWORD = 5;
// Error code returned from {@link #validatePassword(String)}. // Error code returned from {@link #validatePassword(byte[])}.
static final int NO_ERROR = 0; static final int NO_ERROR = 0;
static final int CONTAIN_INVALID_CHARACTERS = 1 << 0; static final int CONTAIN_INVALID_CHARACTERS = 1 << 0;
static final int TOO_SHORT = 1 << 1; static final int TOO_SHORT = 1 << 1;
@@ -394,12 +395,13 @@ public class ChooseLockPassword extends SettingsActivity {
SaveAndFinishWorker w = new SaveAndFinishWorker(); SaveAndFinishWorker w = new SaveAndFinishWorker();
final boolean required = getActivity().getIntent().getBooleanExtra( final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
String current = intent.getStringExtra( byte[] currentBytes = intent.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
w.setBlocking(true); w.setBlocking(true);
w.setListener(this); w.setListener(this);
w.start(mChooseLockSettingsHelper.utils(), required, w.start(mChooseLockSettingsHelper.utils(), required, false, 0,
false, 0, current, current, mRequestedQuality, mUserId); currentBytes, currentBytes, mRequestedQuality, mUserId);
} }
mTextChangedHandler = new TextChangedHandler(); mTextChangedHandler = new TextChangedHandler();
} }
@@ -474,7 +476,8 @@ public class ChooseLockPassword extends SettingsActivity {
Intent intent = getActivity().getIntent(); Intent intent = getActivity().getIntent();
final boolean confirmCredentials = intent.getBooleanExtra( final boolean confirmCredentials = intent.getBooleanExtra(
ChooseLockGeneric.CONFIRM_CREDENTIALS, true); ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
mCurrentPassword = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); mCurrentPassword = intent.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
mHasChallenge = intent.getBooleanExtra( mHasChallenge = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
@@ -486,8 +489,9 @@ public class ChooseLockPassword extends SettingsActivity {
mUserId); mUserId);
} }
} else { } else {
// restore from previous state // restore from previous state
mFirstPin = savedInstanceState.getString(KEY_FIRST_PIN); mFirstPin = savedInstanceState.getByteArray(KEY_FIRST_PIN);
final String state = savedInstanceState.getString(KEY_UI_STAGE); final String state = savedInstanceState.getString(KEY_UI_STAGE);
if (state != null) { if (state != null) {
mUiStage = Stage.valueOf(state); mUiStage = Stage.valueOf(state);
@@ -495,7 +499,7 @@ public class ChooseLockPassword extends SettingsActivity {
} }
if (mCurrentPassword == null) { if (mCurrentPassword == null) {
mCurrentPassword = savedInstanceState.getString(KEY_CURRENT_PASSWORD); mCurrentPassword = savedInstanceState.getByteArray(KEY_CURRENT_PASSWORD);
} }
// Re-attach to the exiting worker if there is one. // Re-attach to the exiting worker if there is one.
@@ -553,8 +557,8 @@ public class ChooseLockPassword extends SettingsActivity {
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putString(KEY_UI_STAGE, mUiStage.name()); outState.putString(KEY_UI_STAGE, mUiStage.name());
outState.putString(KEY_FIRST_PIN, mFirstPin); outState.putByteArray(KEY_FIRST_PIN, mFirstPin);
outState.putString(KEY_CURRENT_PASSWORD, mCurrentPassword); outState.putByteArray(KEY_CURRENT_PASSWORD, mCurrentPassword);
} }
@Override @Override
@@ -567,7 +571,7 @@ public class ChooseLockPassword extends SettingsActivity {
getActivity().setResult(RESULT_FINISHED); getActivity().setResult(RESULT_FINISHED);
getActivity().finish(); getActivity().finish();
} else { } else {
mCurrentPassword = data.getStringExtra( mCurrentPassword = data.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
} }
break; break;
@@ -712,22 +716,22 @@ public class ChooseLockPassword extends SettingsActivity {
* @return the validation result. * @return the validation result.
*/ */
@VisibleForTesting @VisibleForTesting
int validatePassword(String password) { int validatePassword(byte[] password) {
int errorCode = NO_ERROR; int errorCode = NO_ERROR;
final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password); final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
mergeMinComplexityAndDpmRequirements(metrics.quality); mergeMinComplexityAndDpmRequirements(metrics.quality);
if (password.length() < mPasswordMinLength) { if (password == null || password.length < mPasswordMinLength) {
if (mPasswordMinLength > mPasswordMinLengthToFulfillAllPolicies) { if (mPasswordMinLength > mPasswordMinLengthToFulfillAllPolicies) {
errorCode |= TOO_SHORT; errorCode |= TOO_SHORT;
} }
} else if (password.length() > mPasswordMaxLength) { } else if (password.length > mPasswordMaxLength) {
errorCode |= TOO_LONG; errorCode |= TOO_LONG;
} else { } else {
// The length requirements are fulfilled. // The length requirements are fulfilled.
if (!mPasswordNumSequenceAllowed if (!mPasswordNumSequenceAllowed
&& !requiresLettersOrSymbols() && !requiresLettersOrSymbols()
&& metrics.numeric == password.length()) { && metrics.numeric == password.length) {
// Check for repeated characters or sequences (e.g. '1234', '0000', '2468') // Check for repeated characters or sequences (e.g. '1234', '0000', '2468')
// if DevicePolicyManager or min password complexity requires a complex numeric // if DevicePolicyManager or min password complexity requires a complex numeric
// password. There can be two cases in the UI: 1. User chooses to enroll a // password. There can be two cases in the UI: 1. User chooses to enroll a
@@ -757,8 +761,8 @@ public class ChooseLockPassword extends SettingsActivity {
} }
// Allow non-control Latin-1 characters only. // Allow non-control Latin-1 characters only.
for (int i = 0; i < password.length(); i++) { for (int i = 0; i < password.length; i++) {
char c = password.charAt(i); char c = (char) password[i];
if (c < 32 || c > 127) { if (c < 32 || c > 127) {
errorCode |= CONTAIN_INVALID_CHARACTERS; errorCode |= CONTAIN_INVALID_CHARACTERS;
break; break;
@@ -809,8 +813,9 @@ public class ChooseLockPassword extends SettingsActivity {
public void handleNext() { public void handleNext() {
if (mSaveAndFinishWorker != null) return; if (mSaveAndFinishWorker != null) return;
mChosenPassword = mPasswordEntry.getText().toString(); // TODO(b/120484642): This is a point of entry for passwords from the UI
if (TextUtils.isEmpty(mChosenPassword)) { mChosenPassword = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
if (mChosenPassword == null || mChosenPassword.length == 0) {
return; return;
} }
if (mUiStage == Stage.Introduction) { if (mUiStage == Stage.Introduction) {
@@ -818,9 +823,11 @@ public class ChooseLockPassword extends SettingsActivity {
mFirstPin = mChosenPassword; mFirstPin = mChosenPassword;
mPasswordEntry.setText(""); mPasswordEntry.setText("");
updateStage(Stage.NeedToConfirm); updateStage(Stage.NeedToConfirm);
} else {
Arrays.fill(mChosenPassword, (byte) 0);
} }
} else if (mUiStage == Stage.NeedToConfirm) { } else if (mUiStage == Stage.NeedToConfirm) {
if (mFirstPin.equals(mChosenPassword)) { if (Arrays.equals(mFirstPin, mChosenPassword)) {
startSaveAndFinish(); startSaveAndFinish();
} else { } else {
CharSequence tmp = mPasswordEntry.getText(); CharSequence tmp = mPasswordEntry.getText();
@@ -828,6 +835,7 @@ public class ChooseLockPassword extends SettingsActivity {
Selection.setSelection((Spannable) tmp, 0, tmp.length()); Selection.setSelection((Spannable) tmp, 0, tmp.length());
} }
updateStage(Stage.ConfirmWrong); updateStage(Stage.ConfirmWrong);
Arrays.fill(mChosenPassword, (byte) 0);
} }
} }
} }
@@ -940,8 +948,8 @@ public class ChooseLockPassword extends SettingsActivity {
*/ */
protected void updateUi() { protected void updateUi() {
final boolean canInput = mSaveAndFinishWorker == null; final boolean canInput = mSaveAndFinishWorker == null;
String password = mPasswordEntry.getText().toString(); byte[] password = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
final int length = password.length(); final int length = password.length;
if (mUiStage == Stage.Introduction) { if (mUiStage == Stage.Introduction) {
mPasswordRestrictionView.setVisibility(View.VISIBLE); mPasswordRestrictionView.setVisibility(View.VISIBLE);
final int errorCode = validatePassword(password); final int errorCode = validatePassword(password);
@@ -967,6 +975,7 @@ public class ChooseLockPassword extends SettingsActivity {
setNextText(mUiStage.buttonText); setNextText(mUiStage.buttonText);
mPasswordEntryInputDisabler.setInputEnabled(canInput); mPasswordEntryInputDisabler.setInputEnabled(canInput);
Arrays.fill(password, (byte) 0);
} }
protected int toVisibility(boolean visibleOrGone) { protected int toVisibility(boolean visibleOrGone) {
@@ -1025,6 +1034,18 @@ public class ChooseLockPassword extends SettingsActivity {
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) { public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
getActivity().setResult(RESULT_FINISHED, resultData); getActivity().setResult(RESULT_FINISHED, resultData);
if (mChosenPassword != null) {
Arrays.fill(mChosenPassword, (byte) 0);
}
if (mCurrentPassword != null) {
Arrays.fill(mCurrentPassword, (byte) 0);
}
if (mFirstPin != null) {
Arrays.fill(mFirstPin, (byte) 0);
}
mPasswordEntry.setText("");
if (!wasSecureBefore) { if (!wasSecureBefore) {
Intent intent = getRedactionInterstitialIntent(getActivity()); Intent intent = getRedactionInterstitialIntent(getActivity());
if (intent != null) { if (intent != null) {
@@ -1061,13 +1082,13 @@ public class ChooseLockPassword extends SettingsActivity {
public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase { public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
private String mChosenPassword; private byte[] mChosenPassword;
private String mCurrentPassword; private byte[] mCurrentPassword;
private int mRequestedQuality; private int mRequestedQuality;
public void start(LockPatternUtils utils, boolean required, public void start(LockPatternUtils utils, boolean required,
boolean hasChallenge, long challenge, boolean hasChallenge, long challenge,
String chosenPassword, String currentPassword, int requestedQuality, int userId) { byte[] chosenPassword, byte[] currentPassword, int requestedQuality, int userId) {
prepare(utils, required, hasChallenge, challenge, userId); prepare(utils, required, hasChallenge, challenge, userId);
mChosenPassword = chosenPassword; mChosenPassword = chosenPassword;

View File

@@ -55,6 +55,7 @@ import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupdesign.GlifLayout; import com.google.android.setupdesign.GlifLayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -114,7 +115,7 @@ public class ChooseLockPattern extends SettingsActivity {
return this; return this;
} }
public IntentBuilder setPattern(String pattern) { public IntentBuilder setPattern(byte[] pattern) {
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern); mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern);
return this; return this;
} }
@@ -187,7 +188,7 @@ public class ChooseLockPattern extends SettingsActivity {
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker"; private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
private String mCurrentPattern; private byte[] mCurrentPattern;
private boolean mHasChallenge; private boolean mHasChallenge;
private long mChallenge; private long mChallenge;
protected TextView mTitleText; protected TextView mTitleText;
@@ -224,7 +225,7 @@ public class ChooseLockPattern extends SettingsActivity {
getActivity().setResult(RESULT_FINISHED); getActivity().setResult(RESULT_FINISHED);
getActivity().finish(); getActivity().finish();
} else { } else {
mCurrentPattern = data.getStringExtra( mCurrentPattern = data.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
} }
@@ -457,12 +458,12 @@ public class ChooseLockPattern extends SettingsActivity {
SaveAndFinishWorker w = new SaveAndFinishWorker(); SaveAndFinishWorker w = new SaveAndFinishWorker();
final boolean required = getActivity().getIntent().getBooleanExtra( final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
String current = intent.getStringExtra( byte[] current = intent.getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
w.setBlocking(true); w.setBlocking(true);
w.setListener(this); w.setListener(this);
w.start(mChooseLockSettingsHelper.utils(), required, w.start(mChooseLockSettingsHelper.utils(), required,
false, 0, LockPatternUtils.stringToPattern(current), current, mUserId); false, 0, LockPatternUtils.byteArrayToPattern(current), current, mUserId);
} }
mForFingerprint = intent.getBooleanExtra( mForFingerprint = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
@@ -540,7 +541,8 @@ public class ChooseLockPattern extends SettingsActivity {
final boolean confirmCredentials = getActivity().getIntent() final boolean confirmCredentials = getActivity().getIntent()
.getBooleanExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, true); .getBooleanExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
Intent intent = getActivity().getIntent(); Intent intent = getActivity().getIntent();
mCurrentPattern = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); mCurrentPattern =
intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
mHasChallenge = intent.getBooleanExtra( mHasChallenge = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
@@ -563,13 +565,13 @@ public class ChooseLockPattern extends SettingsActivity {
} }
} else { } else {
// restore from previous state // restore from previous state
final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE); final byte[] pattern = savedInstanceState.getByteArray(KEY_PATTERN_CHOICE);
if (patternString != null) { if (pattern != null) {
mChosenPattern = LockPatternUtils.stringToPattern(patternString); mChosenPattern = LockPatternUtils.byteArrayToPattern(pattern);
} }
if (mCurrentPattern == null) { if (mCurrentPattern == null) {
mCurrentPattern = savedInstanceState.getString(KEY_CURRENT_PATTERN); mCurrentPattern = savedInstanceState.getByteArray(KEY_CURRENT_PATTERN);
} }
updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]); updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
@@ -665,13 +667,12 @@ public class ChooseLockPattern extends SettingsActivity {
outState.putInt(KEY_UI_STAGE, mUiStage.ordinal()); outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
if (mChosenPattern != null) { if (mChosenPattern != null) {
outState.putString(KEY_PATTERN_CHOICE, outState.putByteArray(KEY_PATTERN_CHOICE,
LockPatternUtils.patternToString(mChosenPattern)); LockPatternUtils.patternToByteArray(mChosenPattern));
} }
if (mCurrentPattern != null) { if (mCurrentPattern != null) {
outState.putString(KEY_CURRENT_PATTERN, outState.putByteArray(KEY_CURRENT_PATTERN, mCurrentPattern);
mCurrentPattern);
} }
} }
@@ -818,6 +819,10 @@ public class ChooseLockPattern extends SettingsActivity {
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) { public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
getActivity().setResult(RESULT_FINISHED, resultData); getActivity().setResult(RESULT_FINISHED, resultData);
if (mCurrentPattern != null) {
Arrays.fill(mCurrentPattern, (byte) 0);
}
if (!wasSecureBefore) { if (!wasSecureBefore) {
Intent intent = getRedactionInterstitialIntent(getActivity()); Intent intent = getRedactionInterstitialIntent(getActivity());
if (intent != null) { if (intent != null) {
@@ -831,12 +836,12 @@ public class ChooseLockPattern extends SettingsActivity {
public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase { public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
private List<LockPatternView.Cell> mChosenPattern; private List<LockPatternView.Cell> mChosenPattern;
private String mCurrentPattern; private byte[] mCurrentPattern;
private boolean mLockVirgin; private boolean mLockVirgin;
public void start(LockPatternUtils utils, boolean credentialRequired, public void start(LockPatternUtils utils, boolean credentialRequired,
boolean hasChallenge, long challenge, boolean hasChallenge, long challenge,
List<LockPatternView.Cell> chosenPattern, String currentPattern, int userId) { List<LockPatternView.Cell> chosenPattern, byte[] currentPattern, int userId) {
prepare(utils, credentialRequired, hasChallenge, challenge, userId); prepare(utils, credentialRequired, hasChallenge, challenge, userId);
mCurrentPattern = currentPattern; mCurrentPattern = currentPattern;

View File

@@ -323,8 +323,9 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
return; return;
} }
final String pin = mPasswordEntry.getText().toString(); // TODO(b/120484642): This is a point of entry for passwords from the UI
if (TextUtils.isEmpty(pin)) { final byte[] pin = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
if (pin == null || pin.length == 0) {
return; return;
} }
@@ -350,7 +351,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
return getActivity() instanceof ConfirmLockPassword.InternalActivity; return getActivity() instanceof ConfirmLockPassword.InternalActivity;
} }
private void startVerifyPassword(final String pin, final Intent intent) { private void startVerifyPassword(final byte[] pin, final Intent intent) {
long challenge = getActivity().getIntent().getLongExtra( long challenge = getActivity().getIntent().getLongExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
final int localEffectiveUserId = mEffectiveUserId; final int localEffectiveUserId = mEffectiveUserId;
@@ -381,7 +382,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
onVerifyCallback); onVerifyCallback);
} }
private void startCheckPassword(final String pin, final Intent intent) { private void startCheckPassword(final byte[] pin, final Intent intent) {
final int localEffectiveUserId = mEffectiveUserId; final int localEffectiveUserId = mEffectiveUserId;
mPendingLockCheck = LockPatternChecker.checkPassword( mPendingLockCheck = LockPatternChecker.checkPassword(
mLockPatternUtils, mLockPatternUtils,

View File

@@ -448,7 +448,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
mLockPatternUtils, pattern, challenge, localUserId, mLockPatternUtils, pattern, challenge, localUserId,
onVerifyCallback) onVerifyCallback)
: LockPatternChecker.verifyTiedProfileChallenge( : LockPatternChecker.verifyTiedProfileChallenge(
mLockPatternUtils, LockPatternUtils.patternToString(pattern), mLockPatternUtils, LockPatternUtils.patternToByteArray(pattern),
true, challenge, localUserId, onVerifyCallback); true, challenge, localUserId, onVerifyCallback);
} }
@@ -473,7 +473,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
StorageManager.CRYPT_TYPE_PATTERN); StorageManager.CRYPT_TYPE_PATTERN);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
LockPatternUtils.patternToString(pattern)); LockPatternUtils.patternToByteArray(pattern));
} }
mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs, mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs,
localEffectiveUserId); localEffectiveUserId);

View File

@@ -59,7 +59,7 @@ public class ManagedLockPasswordProvider {
* @param password Current lock password. * @param password Current lock password.
* @return Intent that should update lock password to a managed password. * @return Intent that should update lock password to a managed password.
*/ */
Intent createIntent(boolean requirePasswordToDecrypt, String password) { Intent createIntent(boolean requirePasswordToDecrypt, byte[] password) {
return null; return null;
} }
} }

View File

@@ -173,7 +173,7 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
if (helper.utils().getKeyguardStoredPasswordQuality(UserHandle.myUserId()) if (helper.utils().getKeyguardStoredPasswordQuality(UserHandle.myUserId())
== DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, ""); showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "".getBytes());
return true; return true;
} }
@@ -193,14 +193,14 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
// confirmation prompt; otherwise, go back to the initial state. // confirmation prompt; otherwise, go back to the initial state.
if (resultCode == Activity.RESULT_OK && data != null) { if (resultCode == Activity.RESULT_OK && data != null) {
int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1); int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1);
String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); byte[] password = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
if (!TextUtils.isEmpty(password)) { if (!(password == null || password.length == 0)) {
showFinalConfirmation(type, password); showFinalConfirmation(type, password);
} }
} }
} }
private void showFinalConfirmation(int type, String password) { private void showFinalConfirmation(int type, byte[] password) {
Preference preference = new Preference(getPreferenceManager().getContext()); Preference preference = new Preference(getPreferenceManager().getContext());
preference.setFragment(CryptKeeperConfirm.class.getName()); preference.setFragment(CryptKeeperConfirm.class.getName());
preference.setTitle(R.string.crypt_keeper_confirm_title); preference.setTitle(R.string.crypt_keeper_confirm_title);
@@ -208,16 +208,16 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
((SettingsActivity) getActivity()).onPreferenceStartFragment(null, preference); ((SettingsActivity) getActivity()).onPreferenceStartFragment(null, preference);
} }
private void addEncryptionInfoToPreference(Preference preference, int type, String password) { private void addEncryptionInfoToPreference(Preference preference, int type, byte[] password) {
Activity activity = getActivity(); Activity activity = getActivity();
DevicePolicyManager dpm = (DevicePolicyManager) DevicePolicyManager dpm = (DevicePolicyManager)
activity.getSystemService(Context.DEVICE_POLICY_SERVICE); activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (dpm.getDoNotAskCredentialsOnBoot()) { if (dpm.getDoNotAskCredentialsOnBoot()) {
preference.getExtras().putInt(TYPE, StorageManager.CRYPT_TYPE_DEFAULT); preference.getExtras().putInt(TYPE, StorageManager.CRYPT_TYPE_DEFAULT);
preference.getExtras().putString(PASSWORD, ""); preference.getExtras().putByteArray(PASSWORD, "".getBytes());
} else { } else {
preference.getExtras().putInt(TYPE, type); preference.getExtras().putInt(TYPE, type);
preference.getExtras().putString(PASSWORD, password); preference.getExtras().putByteArray(PASSWORD, password);
} }
} }
} }

View File

@@ -70,8 +70,8 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
private RestrictedSwitchPreference mUnifyProfile; private RestrictedSwitchPreference mUnifyProfile;
private String mCurrentDevicePassword; private byte[] mCurrentDevicePassword;
private String mCurrentProfilePassword; private byte[] mCurrentProfilePassword;
private boolean mKeepDeviceLock; private boolean mKeepDeviceLock;
@Override @Override
@@ -151,13 +151,13 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
} else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST } else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) { && resultCode == Activity.RESULT_OK) {
mCurrentDevicePassword = mCurrentDevicePassword =
data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
launchConfirmProfileLock(); launchConfirmProfileLock();
return true; return true;
} else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST } else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
&& resultCode == Activity.RESULT_OK) { && resultCode == Activity.RESULT_OK) {
mCurrentProfilePassword = mCurrentProfilePassword =
data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
unifyLocks(); unifyLocks();
return true; return true;
} }
@@ -226,7 +226,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
// PASSWORD_QUALITY_SOMETHING means pattern, everything above means PIN/password. // PASSWORD_QUALITY_SOMETHING means pattern, everything above means PIN/password.
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern( mLockPatternUtils.saveLockPattern(
LockPatternUtils.stringToPattern(mCurrentProfilePassword), LockPatternUtils.byteArrayToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, MY_USER_ID); mCurrentDevicePassword, MY_USER_ID);
} else { } else {
mLockPatternUtils.saveLockPassword( mLockPatternUtils.saveLockPassword(

View File

@@ -87,7 +87,7 @@ public class ChooseLockPasswordTest {
@Test @Test
public void intentBuilder_setPassword_shouldAddExtras() { public void intentBuilder_setPassword_shouldAddExtras() {
Intent intent = new IntentBuilder(application) Intent intent = new IntentBuilder(application)
.setPassword("password") .setPassword("password".getBytes())
.setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) .setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
.setUserId(123) .setUserId(123)
.build(); .build();
@@ -95,9 +95,9 @@ public class ChooseLockPasswordTest {
assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true)) assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true))
.named("EXTRA_KEY_HAS_CHALLENGE") .named("EXTRA_KEY_HAS_CHALLENGE")
.isFalse(); .isFalse();
assertThat(intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) assertThat(intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
.named("EXTRA_KEY_PASSWORD") .named("EXTRA_KEY_PASSWORD")
.isEqualTo("password"); .isEqualTo("password".getBytes());
assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0)) assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0))
.named("PASSWORD_TYPE_KEY") .named("PASSWORD_TYPE_KEY")
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
@@ -366,7 +366,9 @@ public class ChooseLockPasswordTest {
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, minComplexity); intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, minComplexity);
ChooseLockPassword activity = buildChooseLockPasswordActivity(intent); ChooseLockPassword activity = buildChooseLockPasswordActivity(intent);
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(activity); ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(activity);
int validateResult = fragment.validatePassword(userEnteredPassword); byte[] userEnteredPasswordBytes = userEnteredPassword != null
? userEnteredPassword.getBytes() : null;
int validateResult = fragment.validatePassword(userEnteredPasswordBytes);
String[] messages = fragment.convertErrorCodeToMessages(validateResult); String[] messages = fragment.convertErrorCodeToMessages(validateResult);
assertThat(messages).asList().containsExactly((Object[]) expectedValidationResult); assertThat(messages).asList().containsExactly((Object[]) expectedValidationResult);

View File

@@ -52,7 +52,7 @@ public class ChooseLockPatternTest {
@Test @Test
public void intentBuilder_setPattern_shouldAddExtras() { public void intentBuilder_setPattern_shouldAddExtras() {
Intent intent = new IntentBuilder(application) Intent intent = new IntentBuilder(application)
.setPattern("pattern") .setPattern("pattern".getBytes())
.setUserId(123) .setUserId(123)
.build(); .build();
@@ -61,9 +61,9 @@ public class ChooseLockPatternTest {
.named("EXTRA_KEY_HAS_CHALLENGE") .named("EXTRA_KEY_HAS_CHALLENGE")
.isFalse(); .isFalse();
assertThat(intent assertThat(intent
.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) .getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
.named("EXTRA_KEY_PASSWORD") .named("EXTRA_KEY_PASSWORD")
.isEqualTo("pattern"); .isEqualTo("pattern".getBytes());
assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0)) assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0))
.named("EXTRA_USER_ID") .named("EXTRA_USER_ID")
.isEqualTo(123); .isEqualTo(123);

View File

@@ -66,12 +66,12 @@ public class ShadowLockPatternUtils {
} }
@Implementation @Implementation
protected byte[] getPasswordHistoryHashFactor(String currentPassword, int userId) { protected byte[] getPasswordHistoryHashFactor(byte[] currentPassword, int userId) {
return null; return null;
} }
@Implementation @Implementation
protected boolean checkPasswordHistory(String passwordToCheck, byte[] hashFactor, int userId) { protected boolean checkPasswordHistory(byte[] passwordToCheck, byte[] hashFactor, int userId) {
return false; return false;
} }
} }