Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03908ded authored by Rich Cannings's avatar Rich Cannings Committed by Android (Google) Code Review
Browse files

Merge "Refactor passwords/pins/patterns to byte[]"

parents 40d49647 b27c4308
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -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);
                    }
+8 −7
Original line number Diff line number Diff line
@@ -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);
        }

+49 −28
Original line number Diff line number Diff line
@@ -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;
+21 −16
Original line number Diff line number Diff line
@@ -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<LockPatternView.Cell> mChosenPattern;
        private String mCurrentPattern;
        private byte[] mCurrentPattern;
        private boolean mLockVirgin;

        public void start(LockPatternUtils utils, boolean credentialRequired,
                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);

            mCurrentPattern = currentPattern;
+5 −4
Original line number Diff line number Diff line
@@ -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,
Loading