summaryrefslogtreecommitdiffstats
path: root/services/devicepolicy
diff options
context:
space:
mode:
authorRobin Lee <rgl@google.com>2015-02-03 17:55:31 +0000
committerRobin Lee <rgl@google.com>2015-02-05 19:38:43 +0000
commit3798ed5e0b56ab03e7022a9922b50a4a25474033 (patch)
treeb94913f25a9cbefaadc45bd0f33926498c32e8ef /services/devicepolicy
parentde873a64c8b5751391d3947d0c799b83ac40d7a8 (diff)
downloadframeworks_base-3798ed5e0b56ab03e7022a9922b50a4a25474033.zip
frameworks_base-3798ed5e0b56ab03e7022a9922b50a4a25474033.tar.gz
frameworks_base-3798ed5e0b56ab03e7022a9922b50a4a25474033.tar.bz2
Device Policy API to choose a private key silently
Support for certificate chooser (keychain) to first query a profile owner (if one exists) for a silent credentials grant which will be passed back to the caller as an alias. Bug: 15065444 Change-Id: I0729b435c218b7991e6cb5faedefb7900577afcc
Diffstat (limited to 'services/devicepolicy')
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java54
1 files changed, 54 insertions, 0 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index bec0f66..a91e5c2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -78,6 +78,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.security.Credentials;
+import android.security.IKeyChainAliasCallback;
import android.security.IKeyChainService;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
@@ -2980,6 +2981,59 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return false;
}
+ @Override
+ public void choosePrivateKeyAlias(final String host, int port, final String url,
+ final String alias, final IBinder response) {
+ final ComponentName profileOwner = getProfileOwner(UserHandle.getCallingUserId());
+ final UserHandle caller = Binder.getCallingUserHandle();
+ final int callerUid = Binder.getCallingUid();
+
+ if (profileOwner == null) {
+ sendPrivateKeyAliasResponse(null, response);
+ return;
+ }
+
+ Intent intent = new Intent(DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS);
+ intent.setComponent(profileOwner);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, callerUid);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_HOST, host);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_PORT, port);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URL, url);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS, alias);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE, response);
+
+ final long id = Binder.clearCallingIdentity();
+ try {
+ mContext.sendOrderedBroadcastAsUser(intent, caller, null, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String chosenAlias = getResultData();
+ sendPrivateKeyAliasResponse(chosenAlias, response);
+ }
+ }, null, Activity.RESULT_OK, null, null);
+ } finally {
+ Binder.restoreCallingIdentity(id);
+ }
+ }
+
+ private void sendPrivateKeyAliasResponse(final String alias, final IBinder responseBinder) {
+ final IKeyChainAliasCallback keyChainAliasResponse =
+ IKeyChainAliasCallback.Stub.asInterface(responseBinder);
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... unused) {
+ try {
+ keyChainAliasResponse.alias(alias);
+ } catch (Exception e) {
+ // Catch everything (not just RemoteException): caller could throw a
+ // RuntimeException back across processes.
+ Log.e(LOG_TAG, "error while responding to callback", e);
+ }
+ return null;
+ }
+ }.execute();
+ }
+
private void wipeDataLocked(boolean wipeExtRequested, String reason) {
// If the SD card is encrypted and non-removable, we have to force a wipe.
boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();