Merge "Make Settings aware of legacy user keys with secret key prefix"
This commit is contained in:
committed by
Android (Google) Code Review
commit
7bc0236cc7
@@ -37,6 +37,8 @@ import android.security.IKeyChainService;
|
||||
import android.security.KeyChain;
|
||||
import android.security.KeyChain.KeyChainConnection;
|
||||
import android.security.KeyStore;
|
||||
import android.security.keymaster.KeyCharacteristics;
|
||||
import android.security.keymaster.KeymasterDefs;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
@@ -48,19 +50,15 @@ import android.widget.TextView;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
public class UserCredentialsSettings extends SettingsPreferenceFragment
|
||||
implements View.OnClickListener {
|
||||
private static final String TAG = "UserCredentialsSettings";
|
||||
@@ -254,10 +252,30 @@ public class UserCredentialsSettings extends SettingsPreferenceFragment
|
||||
return credentials;
|
||||
}
|
||||
|
||||
private boolean isAsymmetric(KeyStore keyStore, String alias, int uid)
|
||||
throws UnrecoverableKeyException {
|
||||
KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
|
||||
int errorCode = keyStore.getKeyCharacteristics(alias, null, null, uid,
|
||||
keyCharacteristics);
|
||||
if (errorCode != KeyStore.NO_ERROR) {
|
||||
throw (UnrecoverableKeyException)
|
||||
new UnrecoverableKeyException("Failed to obtain information about key")
|
||||
.initCause(KeyStore.getKeyStoreException(errorCode));
|
||||
}
|
||||
Integer keymasterAlgorithm = keyCharacteristics.getEnum(
|
||||
KeymasterDefs.KM_TAG_ALGORITHM);
|
||||
if (keymasterAlgorithm == null) {
|
||||
throw new UnrecoverableKeyException("Key algorithm unknown");
|
||||
}
|
||||
return keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_RSA ||
|
||||
keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC;
|
||||
}
|
||||
|
||||
private SortedMap<String, Credential> getCredentialsForUid(KeyStore keyStore, int uid) {
|
||||
final SortedMap<String, Credential> aliasMap = new TreeMap<>();
|
||||
for (final Credential.Type type : Credential.Type.values()) {
|
||||
for (final String alias : keyStore.list(type.prefix, uid)) {
|
||||
for (final String prefix : type.prefix) {
|
||||
for (final String alias : keyStore.list(prefix, uid)) {
|
||||
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
|
||||
// Do not show work profile keys in user credentials
|
||||
if (alias.startsWith(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT) ||
|
||||
@@ -269,6 +287,15 @@ public class UserCredentialsSettings extends SettingsPreferenceFragment
|
||||
continue;
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (type == Credential.Type.USER_KEY &&
|
||||
!isAsymmetric(keyStore, prefix + alias, uid)) {
|
||||
continue;
|
||||
}
|
||||
} catch (UnrecoverableKeyException e) {
|
||||
Log.e(TAG, "Unable to determine algorithm of key: " + prefix + alias, e);
|
||||
continue;
|
||||
}
|
||||
Credential c = aliasMap.get(alias);
|
||||
if (c == null) {
|
||||
c = new Credential(alias, uid);
|
||||
@@ -277,6 +304,7 @@ public class UserCredentialsSettings extends SettingsPreferenceFragment
|
||||
c.storedTypes.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return aliasMap;
|
||||
}
|
||||
|
||||
@@ -344,7 +372,7 @@ public class UserCredentialsSettings extends SettingsPreferenceFragment
|
||||
*/
|
||||
private static final SparseArray<Credential.Type> credentialViewTypes = new SparseArray<>();
|
||||
static {
|
||||
credentialViewTypes.put(R.id.contents_userkey, Credential.Type.USER_PRIVATE_KEY);
|
||||
credentialViewTypes.put(R.id.contents_userkey, Credential.Type.USER_KEY);
|
||||
credentialViewTypes.put(R.id.contents_usercrt, Credential.Type.USER_CERTIFICATE);
|
||||
credentialViewTypes.put(R.id.contents_cacrt, Credential.Type.CA_CERTIFICATE);
|
||||
}
|
||||
@@ -380,12 +408,11 @@ public class UserCredentialsSettings extends SettingsPreferenceFragment
|
||||
static enum Type {
|
||||
CA_CERTIFICATE (Credentials.CA_CERTIFICATE),
|
||||
USER_CERTIFICATE (Credentials.USER_CERTIFICATE),
|
||||
USER_PRIVATE_KEY (Credentials.USER_PRIVATE_KEY),
|
||||
USER_SECRET_KEY (Credentials.USER_SECRET_KEY);
|
||||
USER_KEY(Credentials.USER_PRIVATE_KEY, Credentials.USER_SECRET_KEY);
|
||||
|
||||
final String prefix;
|
||||
final String[] prefix;
|
||||
|
||||
Type(String prefix) {
|
||||
Type(String... prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
}
|
||||
@@ -407,8 +434,7 @@ public class UserCredentialsSettings extends SettingsPreferenceFragment
|
||||
* <ul>
|
||||
* <li>{@link Credentials.CA_CERTIFICATE}</li>
|
||||
* <li>{@link Credentials.USER_CERTIFICATE}</li>
|
||||
* <li>{@link Credentials.USER_PRIVATE_KEY}</li>
|
||||
* <li>{@link Credentials.USER_SECRET_KEY}</li>
|
||||
* <li>{@link Credentials.USER_KEY}</li>
|
||||
* </ul>
|
||||
*/
|
||||
final EnumSet<Type> storedTypes = EnumSet.noneOf(Type.class);
|
||||
|
@@ -40,7 +40,7 @@ public class UserCredentialsTest extends InstrumentationTestCase {
|
||||
Credential c = new Credential(alias, Process.SYSTEM_UID);
|
||||
|
||||
c.storedTypes.add(Credential.Type.CA_CERTIFICATE);
|
||||
c.storedTypes.add(Credential.Type.USER_SECRET_KEY);
|
||||
c.storedTypes.add(Credential.Type.USER_KEY);
|
||||
|
||||
Parcel p = Parcel.obtain();
|
||||
c.writeToParcel(p, /* flags */ 0);
|
||||
|
Reference in New Issue
Block a user