CredentialStorage.java revision 7422474c72b05517287fb0c226d1170cb11a064d
191d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh/* 291d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * Copyright (C) 2011 The Android Open Source Project 391d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * 491d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 591d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * you may not use this file except in compliance with the License. 691d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * You may obtain a copy of the License at 791d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * 891d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 991d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * 1091d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * Unless required by applicable law or agreed to in writing, software 1191d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 1291d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1391d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * See the License for the specific language governing permissions and 1491d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh * limitations under the License. 1591d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh */ 1691d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 1791d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehpackage com.android.settings; 1891d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 1991d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.app.Activity; 2091d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.app.AlertDialog; 21d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstromimport android.app.admin.DevicePolicyManager; 2291d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.content.DialogInterface; 2391d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.content.Intent; 240e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstromimport android.content.res.Resources; 259815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstromimport android.os.AsyncTask; 2691d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.os.Bundle; 279815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstromimport android.os.RemoteException; 28cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Rootimport android.os.UserHandle; 29b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Rootimport android.security.Credentials; 30435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstromimport android.security.KeyChain.KeyChainConnection; 31d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstromimport android.security.KeyChain; 3291d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.security.KeyStore; 3391d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.text.Editable; 340e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstromimport android.text.TextUtils; 3591d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.text.TextWatcher; 3691d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.util.Log; 3791d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.view.View; 3891d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.widget.Button; 3991d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.widget.TextView; 4091d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yehimport android.widget.Toast; 41d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstromimport com.android.internal.widget.LockPatternUtils; 4291d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 430e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom/** 440e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * CredentialStorage handles KeyStore reset, unlock, and install. 450e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * 460e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * CredentialStorage has a pretty convoluted state machine to migrate 470e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * from the old style separate keystore password to a new key guard 480e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * based password, as well as to deal with setting up the key guard if 490e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * necessary. 500e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * 510e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyStore: UNINITALIZED 520e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyGuard: OFF 530e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Action: set up key guard 540e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Notes: factory state 550e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * 560e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyStore: UNINITALIZED 570e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyGuard: ON 580e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Action: confirm key guard 590e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Notes: user had key guard but no keystore and upgraded from pre-ICS 600e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * OR user had key guard and pre-ICS keystore password which was then reset 610e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * 620e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyStore: LOCKED 630e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyGuard: OFF/ON 640e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Action: old unlock dialog 650e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Notes: assume old password, need to use it to unlock. 660e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * if unlock, ensure key guard before install. 670e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * if reset, treat as UNINITALIZED/OFF 680e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * 690e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyStore: UNLOCKED 700e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyGuard: OFF 710e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Action: set up key guard 720e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Notes: ensure key guard, then proceed 730e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * 740e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * KeyStore: UNLOCKED 750e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * keyguard: ON 760e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Action: normal unlock/install 770e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Notes: this is the common case 780e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 790e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrompublic final class CredentialStorage extends Activity { 8091d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 81d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private static final String TAG = "CredentialStorage"; 8291d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 8391d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh public static final String ACTION_UNLOCK = "com.android.credentials.UNLOCK"; 8491d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh public static final String ACTION_INSTALL = "com.android.credentials.INSTALL"; 8591d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh public static final String ACTION_RESET = "com.android.credentials.RESET"; 8691d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 87d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom // This is the minimum acceptable password quality. If the current password quality is 88d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom // lower than this, keystore should not be activated. 89d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; 9091d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 910e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private static final int CONFIRM_KEY_GUARD_REQUEST = 1; 920e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 93d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private final KeyStore mKeyStore = KeyStore.getInstance(); 940e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 950e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 960e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * When non-null, the bundle containing credentials to install. 970e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 980e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private Bundle mInstallBundle; 990e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 1000e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 1010e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * After unsuccessful KeyStore.unlock, the number of unlock 1020e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * attempts remaining before the KeyStore will reset itself. 1030e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * 1040e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Reset to -1 on successful unlock or reset. 1050e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 1060e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private int mRetriesRemaining = -1; 10791d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 108cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root @Override 109cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root protected void onResume() { 110d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom super.onResume(); 11191d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 112cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root if (UserHandle.myUserId() != UserHandle.USER_OWNER) { 113cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root Log.i(TAG, "Cannot install to CredentialStorage as non-primary user"); 114cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root finish(); 115cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root return; 116cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root } 117cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root 11891d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh Intent intent = getIntent(); 11991d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh String action = intent.getAction(); 12091d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 12191d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh if (ACTION_RESET.equals(action)) { 122d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom new ResetDialog(); 12391d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } else { 124cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root if (ACTION_INSTALL.equals(action) 125cf008c28b871d4167e5aa19191ca691fb988f8fdKenny Root && "com.android.certinstaller".equals(getCallingPackage())) { 1260e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom mInstallBundle = intent.getExtras(); 1270e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1280e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // ACTION_UNLOCK also handled here in addition to ACTION_INSTALL 1290e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom handleUnlockOrInstall(); 1300e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1310e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1320e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 1330e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 1340e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Based on the current state of the KeyStore and key guard, try to 1350e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * make progress on unlocking or installing to the keystore. 1360e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 1370e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private void handleUnlockOrInstall() { 1380e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // something already decided we are done, do not proceed 1390e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (isFinishing()) { 1400e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 1410e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1420e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom switch (mKeyStore.state()) { 1430e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom case UNINITIALIZED: { 1440e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom ensureKeyGuard(); 1450e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 14691d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 1470e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom case LOCKED: { 1480e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom new UnlockDialog(); 1490e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 15091d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 1510e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom case UNLOCKED: { 1520e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (!checkKeyGuardQuality()) { 1530e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom new ConfigureKeyGuardDialog(); 1540e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 1550e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1560e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom installIfAvailable(); 1570e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom finish(); 1580e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 1590e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1600e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1610e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1620e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 1630e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 1640e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Make sure the user enters the key guard to set or change the 1650e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * keystore password. This can be used in UNINITIALIZED to set the 1660e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * keystore password or UNLOCKED to change the password (as is the 1670e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * case after unlocking with an old-style password). 1680e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 1690e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private void ensureKeyGuard() { 1700e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (!checkKeyGuardQuality()) { 1710e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // key guard not setup, doing so will initialize keystore 1720e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom new ConfigureKeyGuardDialog(); 1730e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // will return to onResume after Activity 1740e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 17591d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 1760e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // force key guard confirmation 1770e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (confirmKeyGuard()) { 1780e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // will return password value via onActivityResult 1790e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 1800e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 1810e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom finish(); 18291d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 18391d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 1840e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 1850e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Returns true if the currently set key guard matches our minimum quality requirements. 1860e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 1870e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private boolean checkKeyGuardQuality() { 188d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom int quality = new LockPatternUtils(this).getActivePasswordQuality(); 189d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom return (quality >= MIN_PASSWORD_QUALITY); 190d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 191d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 1920e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 1930e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Install credentials if available, otherwise do nothing. 1940e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 1950e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private void installIfAvailable() { 1960e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (mInstallBundle != null && !mInstallBundle.isEmpty()) { 1970e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom Bundle bundle = mInstallBundle; 1980e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom mInstallBundle = null; 199b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root 2007422474c72b05517287fb0c226d1170cb11a064dKenny Root final int uid = bundle.getInt(Credentials.EXTRA_INSTALL_AS_UID, -1); 2017422474c72b05517287fb0c226d1170cb11a064dKenny Root 202b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root if (bundle.containsKey(Credentials.EXTRA_USER_PRIVATE_KEY_NAME)) { 203b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root String key = bundle.getString(Credentials.EXTRA_USER_PRIVATE_KEY_NAME); 204b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root byte[] value = bundle.getByteArray(Credentials.EXTRA_USER_PRIVATE_KEY_DATA); 205b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root 2067422474c72b05517287fb0c226d1170cb11a064dKenny Root if (!mKeyStore.importKey(key, value, uid)) { 2077422474c72b05517287fb0c226d1170cb11a064dKenny Root Log.e(TAG, "Failed to install " + key + " as user " + uid); 208d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom return; 20991d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 21091d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 211b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root 212b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root if (bundle.containsKey(Credentials.EXTRA_USER_CERTIFICATE_NAME)) { 213b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root String certName = bundle.getString(Credentials.EXTRA_USER_CERTIFICATE_NAME); 214b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root byte[] certData = bundle.getByteArray(Credentials.EXTRA_USER_CERTIFICATE_DATA); 215b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root 2167422474c72b05517287fb0c226d1170cb11a064dKenny Root if (!mKeyStore.put(certName, certData, uid)) { 2177422474c72b05517287fb0c226d1170cb11a064dKenny Root Log.e(TAG, "Failed to install " + certName + " as user " + uid); 218b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root return; 219b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root } 220b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root } 221b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root 222b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root if (bundle.containsKey(Credentials.EXTRA_CA_CERTIFICATES_NAME)) { 223b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root String caListName = bundle.getString(Credentials.EXTRA_CA_CERTIFICATES_NAME); 224b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root byte[] caListData = bundle.getByteArray(Credentials.EXTRA_CA_CERTIFICATES_DATA); 225b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root 2267422474c72b05517287fb0c226d1170cb11a064dKenny Root if (!mKeyStore.put(caListName, caListData, uid)) { 2277422474c72b05517287fb0c226d1170cb11a064dKenny Root Log.e(TAG, "Failed to install " + caListName + " as user " + uid); 228b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root return; 229b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root } 230b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root } 231b50b15cdbed31e35c2c7f3cbaa7ce06a3feb3a6fKenny Root 232d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom setResult(RESULT_OK); 23391d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 23491d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 23591d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 2360e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 2370e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Prompt for reset confirmation, resetting on confirmation, finishing otherwise. 2380e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 239d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private class ResetDialog 240d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener 241d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom { 242d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private boolean mResetConfirmed; 243d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 244d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private ResetDialog() { 245d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom AlertDialog dialog = new AlertDialog.Builder(CredentialStorage.this) 246d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setTitle(android.R.string.dialog_alert_title) 247e7c53b1c9e48c6f997c47a0ca9a2f190ecbbf586Björn Lundén .setIconAttribute(android.R.attr.alertDialogIcon) 248d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setMessage(R.string.credentials_reset_hint) 249d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setPositiveButton(android.R.string.ok, this) 250d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setNegativeButton(android.R.string.cancel, this) 251d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .create(); 252d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom dialog.setOnDismissListener(this); 253d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom dialog.show(); 25491d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 25591d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 256d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void onClick(DialogInterface dialog, int button) { 257d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mResetConfirmed = (button == DialogInterface.BUTTON_POSITIVE); 25891d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 25991d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh 260d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void onDismiss(DialogInterface dialog) { 261d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom if (mResetConfirmed) { 262d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mResetConfirmed = false; 263d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom new ResetKeyStoreAndKeyChain().execute(); 26491d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh return; 26591d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 266d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom finish(); 26791d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 26891d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh } 2699815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom 2700e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 2710e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Background task to handle reset of both keystore and user installed CAs. 2720e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 2739815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom private class ResetKeyStoreAndKeyChain extends AsyncTask<Void, Void, Boolean> { 2749815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom 2759815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom @Override protected Boolean doInBackground(Void... unused) { 2769815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom 2779815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom mKeyStore.reset(); 2789815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom 2799815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom try { 280435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstrom KeyChainConnection keyChainConnection = KeyChain.bind(CredentialStorage.this); 281435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstrom try { 282435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstrom return keyChainConnection.getService().reset(); 283435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstrom } catch (RemoteException e) { 284435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstrom return false; 285435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstrom } finally { 286435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstrom keyChainConnection.close(); 287435e45e61610bfa50ca54267a72b9ad74c9f1d41Brian Carlstrom } 2889815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom } catch (InterruptedException e) { 2899815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom Thread.currentThread().interrupt(); 2909815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom return false; 2919815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom } 2929815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom } 2939815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom 2949815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom @Override protected void onPostExecute(Boolean success) { 2959815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom if (success) { 2969815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom Toast.makeText(CredentialStorage.this, 2979815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom R.string.credentials_erased, Toast.LENGTH_SHORT).show(); 2989815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom } else { 2999815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom Toast.makeText(CredentialStorage.this, 3009815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom R.string.credentials_not_erased, Toast.LENGTH_SHORT).show(); 3019815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom } 3029815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom finish(); 3039815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom } 3049815429821832c204eaf8edebb37f4e2ff7636f0Brian Carlstrom } 305d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 3060e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 3070e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Prompt for key guard configuration confirmation. 3080e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 3090e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private class ConfigureKeyGuardDialog 310d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener 311d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom { 312d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private boolean mConfigureConfirmed; 313d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 3140e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private ConfigureKeyGuardDialog() { 315d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom AlertDialog dialog = new AlertDialog.Builder(CredentialStorage.this) 316d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setTitle(android.R.string.dialog_alert_title) 317e7c53b1c9e48c6f997c47a0ca9a2f190ecbbf586Björn Lundén .setIconAttribute(android.R.attr.alertDialogIcon) 318d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setMessage(R.string.credentials_configure_lock_screen_hint) 319d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setPositiveButton(android.R.string.ok, this) 320d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setNegativeButton(android.R.string.cancel, this) 321d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .create(); 322d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom dialog.setOnDismissListener(this); 323d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom dialog.show(); 324d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 325d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 326d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void onClick(DialogInterface dialog, int button) { 327d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mConfigureConfirmed = (button == DialogInterface.BUTTON_POSITIVE); 328d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 329d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 330d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void onDismiss(DialogInterface dialog) { 331d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom if (mConfigureConfirmed) { 332d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mConfigureConfirmed = false; 333d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); 334d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, 335d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom MIN_PASSWORD_QUALITY); 336d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom startActivity(intent); 337d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom return; 338d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 339d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom finish(); 340d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 341d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 342d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 3430e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 3440e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Confirm existing key guard, returning password via onActivityResult. 3450e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 3460e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom private boolean confirmKeyGuard() { 3470e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom Resources res = getResources(); 3480e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom boolean launched = new ChooseLockSettingsHelper(this) 3490e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom .launchConfirmationActivity(CONFIRM_KEY_GUARD_REQUEST, 35081d7a806a6403cd98a0c6dd0ba7288d728382144Brian Carlstrom res.getText(R.string.credentials_install_gesture_prompt), 35181d7a806a6403cd98a0c6dd0ba7288d728382144Brian Carlstrom res.getText(R.string.credentials_install_gesture_explanation)); 3520e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return launched; 3530e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 3540e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 3550e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom @Override 3560e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom public void onActivityResult(int requestCode, int resultCode, Intent data) { 3570e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom super.onActivityResult(requestCode, resultCode, data); 3580e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 3590e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 3600e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Receive key guard password initiated by confirmKeyGuard. 3610e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 3620e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (requestCode == CONFIRM_KEY_GUARD_REQUEST) { 3630e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (resultCode == Activity.RESULT_OK) { 3640e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); 3650e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (!TextUtils.isEmpty(password)) { 3660e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // success 3670e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom mKeyStore.password(password); 3680e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // return to onResume 3690e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 3700e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 3710e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 3720e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // failed confirmation, bail 3730e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom finish(); 3740e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 3750e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 3760e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 3770e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom /** 3780e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * Prompt for unlock with old-style password. 3790e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * 3800e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * On successful unlock, ensure migration to key guard before continuing. 3810e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom * On unsuccessful unlock, retry by calling handleUnlockOrInstall. 3820e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom */ 383d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private class UnlockDialog implements TextWatcher, 384d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom DialogInterface.OnClickListener, DialogInterface.OnDismissListener 385d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom { 386d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private boolean mUnlockConfirmed; 387d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 388d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private final Button mButton; 389d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private final TextView mOldPassword; 390d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private final TextView mError; 391d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 392d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom private UnlockDialog() { 393d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom View view = View.inflate(CredentialStorage.this, R.layout.credentials_dialog, null); 394d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 3950e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom CharSequence text; 3960e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom if (mRetriesRemaining == -1) { 3970e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom text = getResources().getText(R.string.credentials_unlock_hint); 3980e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } else if (mRetriesRemaining > 3) { 3990e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom text = getResources().getText(R.string.credentials_wrong_password); 4000e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } else if (mRetriesRemaining == 1) { 4010e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom text = getResources().getText(R.string.credentials_reset_warning); 4020e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } else { 4030e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom text = getString(R.string.credentials_reset_warning_plural, mRetriesRemaining); 4040e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom } 4050e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom 4060e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom ((TextView) view.findViewById(R.id.hint)).setText(text); 407d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mOldPassword = (TextView) view.findViewById(R.id.old_password); 408d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mOldPassword.setVisibility(View.VISIBLE); 409d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mOldPassword.addTextChangedListener(this); 410d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mError = (TextView) view.findViewById(R.id.error); 411d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 412d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom AlertDialog dialog = new AlertDialog.Builder(CredentialStorage.this) 413d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setView(view) 414d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setTitle(R.string.credentials_unlock) 415d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setPositiveButton(android.R.string.ok, this) 416d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .setNegativeButton(android.R.string.cancel, this) 417d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom .create(); 418d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom dialog.setOnDismissListener(this); 419d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom dialog.show(); 420d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE); 421d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mButton.setEnabled(false); 422d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 423d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 424d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void afterTextChanged(Editable editable) { 425d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mButton.setEnabled(mOldPassword == null || mOldPassword.getText().length() > 0); 426d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 427d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 428d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { 429d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 430d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 431d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void onTextChanged(CharSequence s,int start, int before, int count) { 432d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 433d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 434d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void onClick(DialogInterface dialog, int button) { 435d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mUnlockConfirmed = (button == DialogInterface.BUTTON_POSITIVE); 436d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 437d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom 438d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom @Override public void onDismiss(DialogInterface dialog) { 439d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom if (mUnlockConfirmed) { 440d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mUnlockConfirmed = false; 441d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mError.setVisibility(View.VISIBLE); 442d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom mKeyStore.unlock(mOldPassword.getText().toString()); 443d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom int error = mKeyStore.getLastError(); 444d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom if (error == KeyStore.NO_ERROR) { 4450e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom mRetriesRemaining = -1; 446d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom Toast.makeText(CredentialStorage.this, 447d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom R.string.credentials_enabled, 448d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom Toast.LENGTH_SHORT).show(); 4490e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // aha, now we are unlocked, switch to key guard. 4500e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // we'll end up back in onResume to install 4510e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom ensureKeyGuard(); 452d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } else if (error == KeyStore.UNINITIALIZED) { 4530e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom mRetriesRemaining = -1; 454d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom Toast.makeText(CredentialStorage.this, 455d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom R.string.credentials_erased, 456d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom Toast.LENGTH_SHORT).show(); 4570e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // we are reset, we can now set new password with key guard 4580e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom handleUnlockOrInstall(); 459d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } else if (error >= KeyStore.WRONG_PASSWORD) { 4600e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom // we need to try again 4610e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom mRetriesRemaining = error - KeyStore.WRONG_PASSWORD + 1; 4620e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom handleUnlockOrInstall(); 463d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 4640e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom return; 465d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 466d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom finish(); 467d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 468d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom } 46991d65a20af2d1bfb06f32d0bd821e8558afe939dChia-chi Yeh} 470