From b27c4308a2ab839cff4f4751451440f6dc752e8e Mon Sep 17 00:00:00 2001 From: Rich Cannings Date: Tue, 19 Feb 2019 13:15:30 -0800 Subject: [PATCH] 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 --- .../android/settings/CryptKeeperConfirm.java | 8 +- .../settings/password/ChooseLockGeneric.java | 15 ++-- .../settings/password/ChooseLockPassword.java | 77 ++++++++++++------- .../settings/password/ChooseLockPattern.java | 37 +++++---- .../password/ConfirmLockPassword.java | 9 ++- .../settings/password/ConfirmLockPattern.java | 4 +- .../password/ManagedLockPasswordProvider.java | 2 +- .../security/CryptKeeperSettings.java | 14 ++-- .../LockUnificationPreferenceController.java | 10 +-- .../password/ChooseLockPasswordTest.java | 10 ++- .../password/ChooseLockPatternTest.java | 6 +- .../shadow/ShadowLockPatternUtils.java | 4 +- 12 files changed, 116 insertions(+), 80 deletions(-) diff --git a/src/com/android/settings/CryptKeeperConfirm.java b/src/com/android/settings/CryptKeeperConfirm.java index 248494877d3..49d027ba492 100644 --- a/src/com/android/settings/CryptKeeperConfirm.java +++ b/src/com/android/settings/CryptKeeperConfirm.java @@ -38,6 +38,7 @@ import android.widget.Button; import com.android.internal.widget.LockPatternUtils; import com.android.settings.core.InstrumentedFragment; +import java.util.Arrays; import java.util.Locale; public class CryptKeeperConfirm extends InstrumentedFragment { @@ -87,7 +88,12 @@ public class CryptKeeperConfirm extends InstrumentedFragment { IStorageManager storageManager = IStorageManager.Stub.asInterface(service); try { 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) { Log.e("CryptKeeper", "Error while encrypting...", e); } diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java index cf6211246f0..4a758be809a 100644 --- a/src/com/android/settings/password/ChooseLockGeneric.java +++ b/src/com/android/settings/password/ChooseLockGeneric.java @@ -76,6 +76,7 @@ import com.android.settingslib.RestrictedPreference; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.FooterPreferenceMixinCompat; +import java.util.Arrays; import java.util.List; public class ChooseLockGeneric extends SettingsActivity { @@ -151,7 +152,7 @@ public class ChooseLockGeneric extends SettingsActivity { private boolean mPasswordConfirmed = false; private boolean mWaitingForConfirmation = false; private boolean mForChangeCredRequiredForBoot = false; - private String mUserPassword; + private byte[] mUserPassword; private LockPatternUtils mLockPatternUtils; private FingerprintManager mFingerprintManager; private FaceManager mFaceManager; @@ -200,7 +201,7 @@ public class ChooseLockGeneric extends SettingsActivity { .getBooleanExtra(CONFIRM_CREDENTIALS, true); if (getActivity() instanceof ChooseLockGeneric.InternalActivity) { mPasswordConfirmed = !confirmCredentials; - mUserPassword = getActivity().getIntent().getStringExtra( + mUserPassword = getActivity().getIntent().getByteArrayExtra( ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); } @@ -224,7 +225,7 @@ public class ChooseLockGeneric extends SettingsActivity { mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED); mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION); if (mUserPassword == null) { - mUserPassword = savedInstanceState.getString( + mUserPassword = savedInstanceState.getByteArray( ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); } } @@ -383,11 +384,11 @@ public class ChooseLockGeneric extends SettingsActivity { if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) { mPasswordConfirmed = true; mUserPassword = data != null - ? data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD) + ? data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD) : null; updatePreferencesOrFinish(false /* isRecreatingActivity */); if (mForChangeCredRequiredForBoot) { - if (!TextUtils.isEmpty(mUserPassword)) { + if (!(mUserPassword == null || mUserPassword.length == 0)) { maybeEnableEncryption( mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId), false); } else { @@ -447,7 +448,7 @@ public class ChooseLockGeneric extends SettingsActivity { outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed); outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation); 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); } - protected Intent getLockManagedPasswordIntent(String password) { + protected Intent getLockManagedPasswordIntent(byte[] password) { return mManagedPasswordProvider.createIntent(false, password); } diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java index cd481823ec0..c9d1af339d8 100644 --- a/src/com/android/settings/password/ChooseLockPassword.java +++ b/src/com/android/settings/password/ChooseLockPassword.java @@ -78,6 +78,7 @@ import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupdesign.GlifLayout; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class ChooseLockPassword extends SettingsActivity { @@ -123,7 +124,7 @@ public class ChooseLockPassword extends SettingsActivity { return this; } - public IntentBuilder setPassword(String password) { + public IntentBuilder setPassword(byte[] password) { mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password); return this; } @@ -185,8 +186,8 @@ public class ChooseLockPassword extends SettingsActivity { private static final String KEY_CURRENT_PASSWORD = "current_password"; private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker"; - private String mCurrentPassword; - private String mChosenPassword; + private byte[] mCurrentPassword; + private byte[] mChosenPassword; private boolean mHasChallenge; private long mChallenge; private ImeAwareEditText mPasswordEntry; @@ -215,7 +216,7 @@ public class ChooseLockPassword extends SettingsActivity { protected boolean mForFingerprint; protected boolean mForFace; - private String mFirstPin; + private byte[] mFirstPin; private RecyclerView mPasswordRestrictionView; protected boolean mIsAlphaMode; 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_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 CONTAIN_INVALID_CHARACTERS = 1 << 0; static final int TOO_SHORT = 1 << 1; @@ -394,12 +395,13 @@ public class ChooseLockPassword extends SettingsActivity { SaveAndFinishWorker w = new SaveAndFinishWorker(); final boolean required = getActivity().getIntent().getBooleanExtra( EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); - String current = intent.getStringExtra( + byte[] currentBytes = intent.getByteArrayExtra( ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); + w.setBlocking(true); w.setListener(this); - w.start(mChooseLockSettingsHelper.utils(), required, - false, 0, current, current, mRequestedQuality, mUserId); + w.start(mChooseLockSettingsHelper.utils(), required, false, 0, + currentBytes, currentBytes, mRequestedQuality, mUserId); } mTextChangedHandler = new TextChangedHandler(); } @@ -474,7 +476,8 @@ public class ChooseLockPassword extends SettingsActivity { Intent intent = getActivity().getIntent(); final boolean confirmCredentials = intent.getBooleanExtra( ChooseLockGeneric.CONFIRM_CREDENTIALS, true); - mCurrentPassword = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); + mCurrentPassword = intent.getByteArrayExtra( + ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); mHasChallenge = intent.getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); @@ -486,8 +489,9 @@ public class ChooseLockPassword extends SettingsActivity { mUserId); } } else { + // restore from previous state - mFirstPin = savedInstanceState.getString(KEY_FIRST_PIN); + mFirstPin = savedInstanceState.getByteArray(KEY_FIRST_PIN); final String state = savedInstanceState.getString(KEY_UI_STAGE); if (state != null) { mUiStage = Stage.valueOf(state); @@ -495,7 +499,7 @@ public class ChooseLockPassword extends SettingsActivity { } 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. @@ -553,8 +557,8 @@ public class ChooseLockPassword extends SettingsActivity { public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(KEY_UI_STAGE, mUiStage.name()); - outState.putString(KEY_FIRST_PIN, mFirstPin); - outState.putString(KEY_CURRENT_PASSWORD, mCurrentPassword); + outState.putByteArray(KEY_FIRST_PIN, mFirstPin); + outState.putByteArray(KEY_CURRENT_PASSWORD, mCurrentPassword); } @Override @@ -567,7 +571,7 @@ public class ChooseLockPassword extends SettingsActivity { getActivity().setResult(RESULT_FINISHED); getActivity().finish(); } else { - mCurrentPassword = data.getStringExtra( + mCurrentPassword = data.getByteArrayExtra( ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); } break; @@ -712,22 +716,22 @@ public class ChooseLockPassword extends SettingsActivity { * @return the validation result. */ @VisibleForTesting - int validatePassword(String password) { + int validatePassword(byte[] password) { int errorCode = NO_ERROR; final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password); mergeMinComplexityAndDpmRequirements(metrics.quality); - if (password.length() < mPasswordMinLength) { + if (password == null || password.length < mPasswordMinLength) { if (mPasswordMinLength > mPasswordMinLengthToFulfillAllPolicies) { errorCode |= TOO_SHORT; } - } else if (password.length() > mPasswordMaxLength) { + } else if (password.length > mPasswordMaxLength) { errorCode |= TOO_LONG; } else { // The length requirements are fulfilled. if (!mPasswordNumSequenceAllowed && !requiresLettersOrSymbols() - && metrics.numeric == password.length()) { + && metrics.numeric == password.length) { // Check for repeated characters or sequences (e.g. '1234', '0000', '2468') // 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 @@ -757,8 +761,8 @@ public class ChooseLockPassword extends SettingsActivity { } // Allow non-control Latin-1 characters only. - for (int i = 0; i < password.length(); i++) { - char c = password.charAt(i); + for (int i = 0; i < password.length; i++) { + char c = (char) password[i]; if (c < 32 || c > 127) { errorCode |= CONTAIN_INVALID_CHARACTERS; break; @@ -809,8 +813,9 @@ public class ChooseLockPassword extends SettingsActivity { public void handleNext() { if (mSaveAndFinishWorker != null) return; - mChosenPassword = mPasswordEntry.getText().toString(); - if (TextUtils.isEmpty(mChosenPassword)) { + // TODO(b/120484642): This is a point of entry for passwords from the UI + mChosenPassword = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText()); + if (mChosenPassword == null || mChosenPassword.length == 0) { return; } if (mUiStage == Stage.Introduction) { @@ -818,9 +823,11 @@ public class ChooseLockPassword extends SettingsActivity { mFirstPin = mChosenPassword; mPasswordEntry.setText(""); updateStage(Stage.NeedToConfirm); + } else { + Arrays.fill(mChosenPassword, (byte) 0); } } else if (mUiStage == Stage.NeedToConfirm) { - if (mFirstPin.equals(mChosenPassword)) { + if (Arrays.equals(mFirstPin, mChosenPassword)) { startSaveAndFinish(); } else { CharSequence tmp = mPasswordEntry.getText(); @@ -828,6 +835,7 @@ public class ChooseLockPassword extends SettingsActivity { Selection.setSelection((Spannable) tmp, 0, tmp.length()); } updateStage(Stage.ConfirmWrong); + Arrays.fill(mChosenPassword, (byte) 0); } } } @@ -940,8 +948,8 @@ public class ChooseLockPassword extends SettingsActivity { */ protected void updateUi() { final boolean canInput = mSaveAndFinishWorker == null; - String password = mPasswordEntry.getText().toString(); - final int length = password.length(); + byte[] password = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText()); + final int length = password.length; if (mUiStage == Stage.Introduction) { mPasswordRestrictionView.setVisibility(View.VISIBLE); final int errorCode = validatePassword(password); @@ -967,6 +975,7 @@ public class ChooseLockPassword extends SettingsActivity { setNextText(mUiStage.buttonText); mPasswordEntryInputDisabler.setInputEnabled(canInput); + Arrays.fill(password, (byte) 0); } protected int toVisibility(boolean visibleOrGone) { @@ -1025,6 +1034,18 @@ public class ChooseLockPassword extends SettingsActivity { public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent 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) { Intent intent = getRedactionInterstitialIntent(getActivity()); if (intent != null) { @@ -1061,13 +1082,13 @@ public class ChooseLockPassword extends SettingsActivity { public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase { - private String mChosenPassword; - private String mCurrentPassword; + private byte[] mChosenPassword; + private byte[] mCurrentPassword; private int mRequestedQuality; public void start(LockPatternUtils utils, boolean required, 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); mChosenPassword = chosenPassword; diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java index 584cc6162e3..d5ad1abfd70 100644 --- a/src/com/android/settings/password/ChooseLockPattern.java +++ b/src/com/android/settings/password/ChooseLockPattern.java @@ -55,6 +55,7 @@ import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupdesign.GlifLayout; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -114,7 +115,7 @@ public class ChooseLockPattern extends SettingsActivity { return this; } - public IntentBuilder setPattern(String pattern) { + public IntentBuilder setPattern(byte[] pattern) { mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern); 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 String mCurrentPattern; + private byte[] mCurrentPattern; private boolean mHasChallenge; private long mChallenge; protected TextView mTitleText; @@ -224,7 +225,7 @@ public class ChooseLockPattern extends SettingsActivity { getActivity().setResult(RESULT_FINISHED); getActivity().finish(); } else { - mCurrentPattern = data.getStringExtra( + mCurrentPattern = data.getByteArrayExtra( ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); } @@ -457,12 +458,12 @@ public class ChooseLockPattern extends SettingsActivity { SaveAndFinishWorker w = new SaveAndFinishWorker(); final boolean required = getActivity().getIntent().getBooleanExtra( EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); - String current = intent.getStringExtra( + byte[] current = intent.getByteArrayExtra( ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); w.setBlocking(true); w.setListener(this); w.start(mChooseLockSettingsHelper.utils(), required, - false, 0, LockPatternUtils.stringToPattern(current), current, mUserId); + false, 0, LockPatternUtils.byteArrayToPattern(current), current, mUserId); } mForFingerprint = intent.getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); @@ -540,7 +541,8 @@ public class ChooseLockPattern extends SettingsActivity { final boolean confirmCredentials = getActivity().getIntent() .getBooleanExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, true); Intent intent = getActivity().getIntent(); - mCurrentPattern = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); + mCurrentPattern = + intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); mHasChallenge = intent.getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); @@ -563,13 +565,13 @@ public class ChooseLockPattern extends SettingsActivity { } } else { // restore from previous state - final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE); - if (patternString != null) { - mChosenPattern = LockPatternUtils.stringToPattern(patternString); + final byte[] pattern = savedInstanceState.getByteArray(KEY_PATTERN_CHOICE); + if (pattern != null) { + mChosenPattern = LockPatternUtils.byteArrayToPattern(pattern); } if (mCurrentPattern == null) { - mCurrentPattern = savedInstanceState.getString(KEY_CURRENT_PATTERN); + mCurrentPattern = savedInstanceState.getByteArray(KEY_CURRENT_PATTERN); } updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]); @@ -665,13 +667,12 @@ public class ChooseLockPattern extends SettingsActivity { outState.putInt(KEY_UI_STAGE, mUiStage.ordinal()); if (mChosenPattern != null) { - outState.putString(KEY_PATTERN_CHOICE, - LockPatternUtils.patternToString(mChosenPattern)); + outState.putByteArray(KEY_PATTERN_CHOICE, + LockPatternUtils.patternToByteArray(mChosenPattern)); } if (mCurrentPattern != null) { - outState.putString(KEY_CURRENT_PATTERN, - mCurrentPattern); + outState.putByteArray(KEY_CURRENT_PATTERN, mCurrentPattern); } } @@ -818,6 +819,10 @@ public class ChooseLockPattern extends SettingsActivity { public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) { getActivity().setResult(RESULT_FINISHED, resultData); + if (mCurrentPattern != null) { + Arrays.fill(mCurrentPattern, (byte) 0); + } + if (!wasSecureBefore) { Intent intent = getRedactionInterstitialIntent(getActivity()); if (intent != null) { @@ -831,12 +836,12 @@ public class ChooseLockPattern extends SettingsActivity { public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase { private List mChosenPattern; - private String mCurrentPattern; + private byte[] mCurrentPattern; private boolean mLockVirgin; public void start(LockPatternUtils utils, boolean credentialRequired, boolean hasChallenge, long challenge, - List chosenPattern, String currentPattern, int userId) { + List chosenPattern, byte[] currentPattern, int userId) { prepare(utils, credentialRequired, hasChallenge, challenge, userId); mCurrentPattern = currentPattern; diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java index f8938703bd7..6c619674d5f 100644 --- a/src/com/android/settings/password/ConfirmLockPassword.java +++ b/src/com/android/settings/password/ConfirmLockPassword.java @@ -323,8 +323,9 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity { return; } - final String pin = mPasswordEntry.getText().toString(); - if (TextUtils.isEmpty(pin)) { + // TODO(b/120484642): This is a point of entry for passwords from the UI + final byte[] pin = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText()); + if (pin == null || pin.length == 0) { return; } @@ -350,7 +351,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity { 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( ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); final int localEffectiveUserId = mEffectiveUserId; @@ -381,7 +382,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity { onVerifyCallback); } - private void startCheckPassword(final String pin, final Intent intent) { + private void startCheckPassword(final byte[] pin, final Intent intent) { final int localEffectiveUserId = mEffectiveUserId; mPendingLockCheck = LockPatternChecker.checkPassword( mLockPatternUtils, diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java index 29cdfef0516..6d3d6e56cfc 100644 --- a/src/com/android/settings/password/ConfirmLockPattern.java +++ b/src/com/android/settings/password/ConfirmLockPattern.java @@ -448,7 +448,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity { mLockPatternUtils, pattern, challenge, localUserId, onVerifyCallback) : LockPatternChecker.verifyTiedProfileChallenge( - mLockPatternUtils, LockPatternUtils.patternToString(pattern), + mLockPatternUtils, LockPatternUtils.patternToByteArray(pattern), true, challenge, localUserId, onVerifyCallback); } @@ -473,7 +473,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity { intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, StorageManager.CRYPT_TYPE_PATTERN); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, - LockPatternUtils.patternToString(pattern)); + LockPatternUtils.patternToByteArray(pattern)); } mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs, localEffectiveUserId); diff --git a/src/com/android/settings/password/ManagedLockPasswordProvider.java b/src/com/android/settings/password/ManagedLockPasswordProvider.java index 2494af556ed..5006926feb1 100644 --- a/src/com/android/settings/password/ManagedLockPasswordProvider.java +++ b/src/com/android/settings/password/ManagedLockPasswordProvider.java @@ -59,7 +59,7 @@ public class ManagedLockPasswordProvider { * @param password Current lock 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; } } diff --git a/src/com/android/settings/security/CryptKeeperSettings.java b/src/com/android/settings/security/CryptKeeperSettings.java index c80ad115ff5..6555f568947 100644 --- a/src/com/android/settings/security/CryptKeeperSettings.java +++ b/src/com/android/settings/security/CryptKeeperSettings.java @@ -173,7 +173,7 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment { if (helper.utils().getKeyguardStoredPasswordQuality(UserHandle.myUserId()) == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { - showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, ""); + showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "".getBytes()); return true; } @@ -193,14 +193,14 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment { // confirmation prompt; otherwise, go back to the initial state. if (resultCode == Activity.RESULT_OK && data != null) { int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1); - String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); - if (!TextUtils.isEmpty(password)) { + byte[] password = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); + if (!(password == null || password.length == 0)) { showFinalConfirmation(type, password); } } } - private void showFinalConfirmation(int type, String password) { + private void showFinalConfirmation(int type, byte[] password) { Preference preference = new Preference(getPreferenceManager().getContext()); preference.setFragment(CryptKeeperConfirm.class.getName()); preference.setTitle(R.string.crypt_keeper_confirm_title); @@ -208,16 +208,16 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment { ((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(); DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE); if (dpm.getDoNotAskCredentialsOnBoot()) { preference.getExtras().putInt(TYPE, StorageManager.CRYPT_TYPE_DEFAULT); - preference.getExtras().putString(PASSWORD, ""); + preference.getExtras().putByteArray(PASSWORD, "".getBytes()); } else { preference.getExtras().putInt(TYPE, type); - preference.getExtras().putString(PASSWORD, password); + preference.getExtras().putByteArray(PASSWORD, password); } } } diff --git a/src/com/android/settings/security/LockUnificationPreferenceController.java b/src/com/android/settings/security/LockUnificationPreferenceController.java index 978986c4c83..bf374de81cf 100644 --- a/src/com/android/settings/security/LockUnificationPreferenceController.java +++ b/src/com/android/settings/security/LockUnificationPreferenceController.java @@ -70,8 +70,8 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr private RestrictedSwitchPreference mUnifyProfile; - private String mCurrentDevicePassword; - private String mCurrentProfilePassword; + private byte[] mCurrentDevicePassword; + private byte[] mCurrentProfilePassword; private boolean mKeepDeviceLock; @Override @@ -151,13 +151,13 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr } else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST && resultCode == Activity.RESULT_OK) { mCurrentDevicePassword = - data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); + data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); launchConfirmProfileLock(); return true; } else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST && resultCode == Activity.RESULT_OK) { mCurrentProfilePassword = - data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); + data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); unifyLocks(); return true; } @@ -226,7 +226,7 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr // PASSWORD_QUALITY_SOMETHING means pattern, everything above means PIN/password. if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { mLockPatternUtils.saveLockPattern( - LockPatternUtils.stringToPattern(mCurrentProfilePassword), + LockPatternUtils.byteArrayToPattern(mCurrentProfilePassword), mCurrentDevicePassword, MY_USER_ID); } else { mLockPatternUtils.saveLockPassword( diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java index 404d2057aa4..73707a63012 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java @@ -87,7 +87,7 @@ public class ChooseLockPasswordTest { @Test public void intentBuilder_setPassword_shouldAddExtras() { Intent intent = new IntentBuilder(application) - .setPassword("password") + .setPassword("password".getBytes()) .setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) .setUserId(123) .build(); @@ -95,9 +95,9 @@ public class ChooseLockPasswordTest { assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true)) .named("EXTRA_KEY_HAS_CHALLENGE") .isFalse(); - assertThat(intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) + assertThat(intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) .named("EXTRA_KEY_PASSWORD") - .isEqualTo("password"); + .isEqualTo("password".getBytes()); assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0)) .named("PASSWORD_TYPE_KEY") .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); @@ -366,7 +366,9 @@ public class ChooseLockPasswordTest { intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, minComplexity); ChooseLockPassword activity = buildChooseLockPasswordActivity(intent); 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); assertThat(messages).asList().containsExactly((Object[]) expectedValidationResult); diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java index 6b1029c7237..3509d75ab81 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java @@ -52,7 +52,7 @@ public class ChooseLockPatternTest { @Test public void intentBuilder_setPattern_shouldAddExtras() { Intent intent = new IntentBuilder(application) - .setPattern("pattern") + .setPattern("pattern".getBytes()) .setUserId(123) .build(); @@ -61,9 +61,9 @@ public class ChooseLockPatternTest { .named("EXTRA_KEY_HAS_CHALLENGE") .isFalse(); assertThat(intent - .getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) + .getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) .named("EXTRA_KEY_PASSWORD") - .isEqualTo("pattern"); + .isEqualTo("pattern".getBytes()); assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0)) .named("EXTRA_USER_ID") .isEqualTo(123); diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java index f2870854750..e9be346eb20 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java @@ -66,12 +66,12 @@ public class ShadowLockPatternUtils { } @Implementation - protected byte[] getPasswordHistoryHashFactor(String currentPassword, int userId) { + protected byte[] getPasswordHistoryHashFactor(byte[] currentPassword, int userId) { return null; } @Implementation - protected boolean checkPasswordHistory(String passwordToCheck, byte[] hashFactor, int userId) { + protected boolean checkPasswordHistory(byte[] passwordToCheck, byte[] hashFactor, int userId) { return false; } }