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:
@@ -275,6 +275,16 @@ public final class CredentialStorage extends Activity {
|
|||||||
Log.e(TAG, "Failed to install " + key + " as uid " + uid);
|
Log.e(TAG, "Failed to install " + key + " as uid " + uid);
|
||||||
return;
|
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;
|
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.
|
* Check that the caller is either certinstaller or Settings running in a profile of this user.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user