diff options
author | Robin Lee <rgl@google.com> | 2015-02-03 17:55:31 +0000 |
---|---|---|
committer | Robin Lee <rgl@google.com> | 2015-02-05 19:38:43 +0000 |
commit | 3798ed5e0b56ab03e7022a9922b50a4a25474033 (patch) | |
tree | b94913f25a9cbefaadc45bd0f33926498c32e8ef /services/devicepolicy/java | |
parent | de873a64c8b5751391d3947d0c799b83ac40d7a8 (diff) | |
download | frameworks_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/java')
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 54 |
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(); |