CredentialStorage: Fix manual key installation.

Since the introduction of user-selectability of keys into KeyChain,
keys installed in KeyChain, by default, cannot be granted access
by the user. This is a secure default, and means keys manually
installed by the user should be explicitly marked as user-selectable.

This change marks the user-added alias as user-selectable, so it can be
selected, later on, by the user, from the Certificate Selection prompt.

Bug: 65624467
Test: Manually with CtsVerifier (KeyChainTest).
Change-Id: I618a06270a127a38b2aa3098fddfa518515bc1b1
This commit is contained in:
Eran Messeri
2017-11-22 17:29:38 +00:00
parent 03b2d4c44c
commit e0f7721ae2

View File

@@ -275,6 +275,16 @@ public final class CredentialStorage extends Activity {
Log.e(TAG, "Failed to install " + key + " as uid " + uid);
return;
}
// The key was prepended USER_PRIVATE_KEY by the CredentialHelper. However,
// KeyChain internally uses the raw alias name and only prepends USER_PRIVATE_KEY
// to the key name when interfacing with KeyStore.
// This is generally a symptom of CredentialStorage and CredentialHelper relying
// on internal implementation details of KeyChain and imitating its functionality
// rather than delegating to KeyChain for the certificate installation.
if (uid == Process.SYSTEM_UID || uid == KeyStore.UID_SELF) {
new MarkKeyAsUserSelectable(
key.replaceFirst("^" + Credentials.USER_PRIVATE_KEY, "")).execute();
}
}
int flags = KeyStore.FLAG_NONE;
@@ -390,6 +400,33 @@ public final class CredentialStorage extends Activity {
}
}
/**
* Background task to mark a given key alias as user-selectable, so that
* it can be selected by users from the Certificate Selection prompt.
*/
private class MarkKeyAsUserSelectable extends AsyncTask<Void, Void, Boolean> {
final String mAlias;
public MarkKeyAsUserSelectable(String alias) {
mAlias = alias;
}
@Override
protected Boolean doInBackground(Void... unused) {
try (KeyChainConnection keyChainConnection = KeyChain.bind(CredentialStorage.this)) {
keyChainConnection.getService().setUserSelectable(mAlias, true);
return true;
} catch (RemoteException e) {
Log.w(TAG, "Failed to mark key " + mAlias + " as user-selectable.");
return false;
} catch (InterruptedException e) {
Log.w(TAG, "Failed to mark key " + mAlias + " as user-selectable.");
Thread.currentThread().interrupt();
return false;
}
}
}
/**
* Check that the caller is either certinstaller or Settings running in a profile of this user.
*/