pipe auth token through confirm and set password
ConfirmDeviceCredentialsActivity and ChooseLockGeneric now understand
CLSH.EXTRA_KEY_HAS_CHALLENGE and CLSH.EXTRA_KEY_CHALLENGE in their
launching intents. If present, they return a hw_auth_token_t verifying
the challenge passed in as a field in keyed by
CLSH.EXTRA_KEY_CHALLENGE_TOKEN in their result intents.
Change-Id: I0b4e02b6a798a9e57d02522880a180dffadfcde1
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 51614a6..a53eca0 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -89,6 +89,8 @@
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private DevicePolicyManager mDPM;
private KeyStore mKeyStore;
+ private boolean mHasChallenge = false;
+ private long mChallenge;
private boolean mPasswordConfirmed = false;
private boolean mWaitingForConfirmation = false;
private int mEncryptionRequestQuality;
@@ -133,6 +135,11 @@
mPasswordConfirmed = !confirmCredentials;
}
+ mHasChallenge = getActivity().getIntent().getBooleanExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
+ mChallenge = getActivity().getIntent().getLongExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
+
if (savedInstanceState != null) {
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
@@ -389,8 +396,13 @@
maxLength, requirePasswordToDecrypt, confirmCredentials);
}
- // SetupWizard version will not need this as they will never be changing a password
- // TODO: confirm
+ protected Intent getLockPasswordIntent(Context context, int quality,
+ int minLength, final int maxLength,
+ boolean requirePasswordToDecrypt, long challenge) {
+ return ChooseLockPassword.createIntent(context, quality, minLength,
+ maxLength, requirePasswordToDecrypt, challenge);
+ }
+
private Intent getLockPasswordIntent(Context context, int quality, int minLength,
final int maxLength, boolean requirePasswordToDecrypt, String password) {
return ChooseLockPassword.createIntent(context, quality, minLength, maxLength,
@@ -403,8 +415,11 @@
confirmCredentials);
}
- // SetupWizard version will not need this as they will never be changing a password
- // TODO: confirm
+ protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
+ long challenge) {
+ return ChooseLockPattern.createIntent(context, requirePassword, challenge);
+ }
+
private Intent getLockPatternIntent(Context context, final boolean requirePassword,
final String pattern) {
return ChooseLockPattern.createIntent(context, requirePassword, pattern);
@@ -439,12 +454,24 @@
minLength = MIN_PASSWORD_LENGTH;
}
final int maxLength = mDPM.getPasswordMaximumLength(quality);
- Intent intent = getLockPasswordIntent(context, quality, minLength,
+ Intent intent;
+ if (mHasChallenge) {
+ intent = getLockPasswordIntent(context, quality, minLength,
+ maxLength, mRequirePassword, mChallenge);
+ } else {
+ intent = getLockPasswordIntent(context, quality, minLength,
maxLength, mRequirePassword, mUserPassword);
+ }
startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
} else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
- Intent intent = getLockPatternIntent(context, mRequirePassword,
+ Intent intent;
+ if (mHasChallenge) {
+ intent = getLockPatternIntent(context, mRequirePassword,
+ mChallenge);
+ } else {
+ intent = getLockPatternIntent(context, mRequirePassword,
mUserPassword);
+ }
startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
} else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
mChooseLockSettingsHelper.utils().clearLock();
diff --git a/src/com/android/settings/ChooseLockPassword.java b/src/com/android/settings/ChooseLockPassword.java
index 7ef044a..4e28eab 100644
--- a/src/com/android/settings/ChooseLockPassword.java
+++ b/src/com/android/settings/ChooseLockPassword.java
@@ -84,6 +84,15 @@
return intent;
}
+ public static Intent createIntent(Context context, int quality,
+ int minLength, final int maxLength, boolean requirePasswordToDecrypt, long challenge) {
+ Intent intent = createIntent(context, quality, minLength, maxLength, requirePasswordToDecrypt,
+ false);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
+ return intent;
+ }
+
@Override
protected boolean isValidFragment(String fragmentName) {
if (ChooseLockPasswordFragment.class.getName().equals(fragmentName)) return true;
@@ -112,6 +121,8 @@
private static final String KEY_CURRENT_PASSWORD = "current_password";
private String mCurrentPassword;
+ private boolean mHasChallenge;
+ private long mChallenge;
private TextView mPasswordEntry;
private int mPasswordMinLength = LockPatternUtils.MIN_LOCK_PASSWORD_SIZE;
private int mPasswordMaxLength = 16;
@@ -249,8 +260,12 @@
: (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD));
Intent intent = getActivity().getIntent();
- final boolean confirmCredentials = intent.getBooleanExtra("confirm_credentials", true);
+ final boolean confirmCredentials = intent.getBooleanExtra(
+ ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
mCurrentPassword = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ mHasChallenge = intent.getBooleanExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
+ mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
if (savedInstanceState == null) {
updateStage(Stage.Introduction);
if (confirmCredentials) {
@@ -463,7 +478,15 @@
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
mLockPatternUtils.setCredentialRequiredToDecrypt(required);
mLockPatternUtils.saveLockPassword(pin, mCurrentPassword, mRequestedQuality);
- getActivity().setResult(RESULT_FINISHED);
+
+ if (mHasChallenge) {
+ Intent intent = new Intent();
+ byte[] token = mLockPatternUtils.verifyPassword(pin, mChallenge);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
+ getActivity().setResult(RESULT_FINISHED, intent);
+ } else {
+ getActivity().setResult(RESULT_FINISHED);
+ }
getActivity().finish();
mDone = true;
if (!wasSecureBefore) {
diff --git a/src/com/android/settings/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java
index c516ad0..e3b7d4b 100644
--- a/src/com/android/settings/ChooseLockPattern.java
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -84,6 +84,15 @@
return intent;
}
+
+ public static Intent createIntent(Context context,
+ boolean requirePassword, long challenge) {
+ Intent intent = createIntent(context, requirePassword, false);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
+ return intent;
+ }
+
@Override
protected boolean isValidFragment(String fragmentName) {
if (ChooseLockPatternFragment.class.getName().equals(fragmentName)) return true;
@@ -123,6 +132,8 @@
private static final int ID_EMPTY_MESSAGE = -1;
private String mCurrentPattern;
+ private boolean mHasChallenge;
+ private long mChallenge;
protected TextView mHeaderText;
protected LockPatternView mLockPatternView;
protected TextView mFooterText;
@@ -384,8 +395,11 @@
final boolean confirmCredentials = getActivity().getIntent()
.getBooleanExtra("confirm_credentials", true);
- mCurrentPattern = getActivity().getIntent()
- .getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ Intent intent = getActivity().getIntent();
+ mCurrentPattern = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ mHasChallenge = intent.getBooleanExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
+ mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
if (savedInstanceState == null) {
if (confirmCredentials) {
@@ -606,7 +620,16 @@
if (!wasSecureBefore) {
startActivity(getRedactionInterstitialIntent(getActivity()));
}
- getActivity().setResult(RESULT_FINISHED);
+
+ if (mHasChallenge) {
+ Intent intent = new Intent();
+ byte[] token = utils.verifyPattern(mChosenPattern, mChallenge);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
+ getActivity().setResult(RESULT_FINISHED, intent);
+ } else {
+ getActivity().setResult(RESULT_FINISHED);
+ }
+
getActivity().finish();
mDone = true;
}
diff --git a/src/com/android/settings/ChooseLockSettingsHelper.java b/src/com/android/settings/ChooseLockSettingsHelper.java
index 65697f6..c113b1d 100644
--- a/src/com/android/settings/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/ChooseLockSettingsHelper.java
@@ -28,6 +28,10 @@
static final String EXTRA_KEY_TYPE = "type";
static final String EXTRA_KEY_PASSWORD = "password";
+ static final String EXTRA_KEY_HAS_CHALLENGE = "has_challenge";
+ static final String EXTRA_KEY_CHALLENGE = "challenge";
+ static final String EXTRA_KEY_CHALLENGE_TOKEN = "hw_auth_token";
+
private LockPatternUtils mLockPatternUtils;
private Activity mActivity;
@@ -87,13 +91,38 @@
boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description,
boolean returnCredentials, boolean external) {
+ return launchConfirmationActivity(request, title, header, description,
+ returnCredentials, external, false, 0);
+ }
+
+ /**
+ * If a pattern, password or PIN exists, prompt the user before allowing them to change it.
+ * @param message optional message to display about the action about to be done
+ * @param details optional detail message to display
+ * @param challenge a challenge to be verified against the device credential.
+ * This method can only be called internally.
+ * @return true if one exists and we launched an activity to confirm it
+ * @see #onActivityResult(int, int, android.content.Intent)
+ */
+ boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
+ @Nullable CharSequence header, @Nullable CharSequence description,
+ long challenge) {
+ return launchConfirmationActivity(request, title, header, description,
+ false, false, true, challenge);
+ }
+
+ private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
+ @Nullable CharSequence header, @Nullable CharSequence description,
+ boolean returnCredentials, boolean external, boolean hasChallenge,
+ long challenge) {
boolean launched = false;
switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
launched = launchConfirmationActivity(request, title, header, description,
- returnCredentials
+ returnCredentials || hasChallenge
? ConfirmLockPattern.InternalActivity.class
- : ConfirmLockPattern.class, external);
+ : ConfirmLockPattern.class, external,
+ hasChallenge, challenge);
break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
@@ -101,16 +130,18 @@
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
launched = launchConfirmationActivity(request, title, header, description,
- returnCredentials
+ returnCredentials || hasChallenge
? ConfirmLockPassword.InternalActivity.class
- : ConfirmLockPassword.class, external);
+ : ConfirmLockPassword.class, external,
+ hasChallenge, challenge);
break;
}
return launched;
}
private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
- CharSequence message, Class<?> activityClass, boolean external) {
+ CharSequence message, Class<?> activityClass, boolean external, boolean hasChallenge,
+ long challenge) {
final Intent intent = new Intent();
intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header);
@@ -119,6 +150,8 @@
intent.putExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, external);
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_CANCEL_BUTTON, external);
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, hasChallenge);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
intent.setClassName(ConfirmDeviceCredentialBaseFragment.PACKAGE, activityClass.getName());
if (mFragment != null) {
mFragment.startActivityForResult(intent, request);
diff --git a/src/com/android/settings/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/ConfirmDeviceCredentialActivity.java
index 9a7f843..7653603 100644
--- a/src/com/android/settings/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/ConfirmDeviceCredentialActivity.java
@@ -39,6 +39,17 @@
return intent;
}
+ public static Intent createIntent(CharSequence title, CharSequence details, long challenge) {
+ Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ ConfirmDeviceCredentialActivity.class.getName());
+ intent.putExtra(KeyguardManager.EXTRA_TITLE, title);
+ intent.putExtra(KeyguardManager.EXTRA_DESCRIPTION, details);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
+ return intent;
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index 44c599b..d9622c0 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -183,8 +183,34 @@
private void handleNext() {
final String pin = mPasswordEntry.getText().toString();
- if (mLockPatternUtils.checkPassword(pin)) {
+ final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
+ boolean matched = false;
+ Intent intent = new Intent();
+ if (verifyChallenge) {
+ if (getActivity() instanceof ConfirmLockPassword.InternalActivity) {
+ long challenge = getActivity().getIntent().getLongExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
+ byte[] token = mLockPatternUtils.verifyPassword(pin, challenge);
+ if (token != null) {
+ matched = true;
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
+ }
+ }
+ } else if (mLockPatternUtils.checkPassword(pin)) {
+ matched = true;
+ if (getActivity() instanceof ConfirmLockPassword.InternalActivity) {
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
+ mIsAlpha ? StorageManager.CRYPT_TYPE_PASSWORD
+ : StorageManager.CRYPT_TYPE_PIN);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pin);
+ }
+ }
+
+ if (matched) {
authenticationSucceeded(pin);
+ getActivity().setResult(RESULT_OK, intent);
+ getActivity().finish();
} else {
if (++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java
index 8c4fabc..9db1719 100644
--- a/src/com/android/settings/ConfirmLockPattern.java
+++ b/src/com/android/settings/ConfirmLockPattern.java
@@ -273,8 +273,35 @@
}
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
- if (mLockPatternUtils.checkPattern(pattern)) {
+ final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
+ boolean matched = false;
+ Intent intent = new Intent();
+ if (verifyChallenge) {
+ if (getActivity() instanceof ConfirmLockPattern.InternalActivity) {
+ long challenge = getActivity().getIntent().getLongExtra(
+ ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
+ byte[] token = mLockPatternUtils.verifyPattern(pattern, challenge);
+ if (token != null) {
+ matched = true;
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
+ }
+ }
+ } else if (mLockPatternUtils.checkPattern(pattern)) {
+ matched = true;
+ if (getActivity() instanceof ConfirmLockPattern.InternalActivity) {
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
+ StorageManager.CRYPT_TYPE_PATTERN);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
+ LockPatternUtils.patternToString(pattern));
+ }
+
+ }
+
+ if (matched) {
authenticationSucceeded(LockPatternUtils.patternToString(pattern));
+ getActivity().setResult(Activity.RESULT_OK, intent);
+ getActivity().finish();
} else {
if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL &&
++mNumWrongConfirmAttempts