diff options
author | 2017-11-22 17:12:29 +0000 | |
---|---|---|
committer | 2017-11-22 17:12:29 +0000 | |
commit | 3daba14f2598956eb2b303e34e39717c326cb8df (patch) | |
tree | 34af17993905fdc6aa33afc8fbbbf4b22211d7dd | |
parent | 7430d8d89667a39c5f993dc46c00c98814382f72 (diff) | |
parent | 19d19048e46a44f9cd92f9b3c2b45d9603283f15 (diff) |
Merge "DevicePolicyManager: Make installed keys user-selectable by default."
-rw-r--r-- | api/current.txt | 1 | ||||
-rw-r--r-- | api/system-current.txt | 1 | ||||
-rw-r--r-- | api/test-current.txt | 1 | ||||
-rw-r--r-- | core/java/android/app/admin/DevicePolicyManager.java | 43 | ||||
-rw-r--r-- | core/java/android/app/admin/IDevicePolicyManager.aidl | 3 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 4 |
6 files changed, 50 insertions, 3 deletions
diff --git a/api/current.txt b/api/current.txt index e5f41be47f50..ec13b5560d37 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6377,6 +6377,7 @@ package android.app.admin { method public boolean installCaCert(android.content.ComponentName, byte[]); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean); + method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean, boolean); method public boolean isActivePasswordSufficient(); method public boolean isAdminActive(android.content.ComponentName); method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String); diff --git a/api/system-current.txt b/api/system-current.txt index e08e17272743..ce3d27795d22 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6605,6 +6605,7 @@ package android.app.admin { method public boolean installCaCert(android.content.ComponentName, byte[]); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean); + method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean, boolean); method public boolean isActivePasswordSufficient(); method public boolean isAdminActive(android.content.ComponentName); method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String); diff --git a/api/test-current.txt b/api/test-current.txt index 67925981b4d7..8a718f588d70 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -6446,6 +6446,7 @@ package android.app.admin { method public boolean installCaCert(android.content.ComponentName, byte[]); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String); method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean); + method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean, boolean); method public boolean isActivePasswordSufficient(); method public boolean isAdminActive(android.content.ComponentName); method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index f0226b7e848f..0bca96907988 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -3858,6 +3858,47 @@ public class DevicePolicyManager { */ public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey, @NonNull Certificate[] certs, @NonNull String alias, boolean requestAccess) { + return installKeyPair(admin, privKey, certs, alias, requestAccess, true); + } + + /** + * Called by a device or profile owner, or delegated certificate installer, to install a + * certificate chain and corresponding private key for the leaf certificate. All apps within the + * profile will be able to access the certificate chain and use the private key, given direct + * user approval (if the user is allowed to select the private key). + * + * <p>The caller of this API may grant itself access to the certificate and private key + * immediately, without user approval. It is a best practice not to request this unless strictly + * necessary since it opens up additional security vulnerabilities. + * + * <p>Whether this key is offered to the user for approval at all or not depends on the + * {@code isUserSelectable} parameter. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if calling from a delegated certificate installer. + * @param privKey The private key to install. + * @param certs The certificate chain to install. The chain should start with the leaf + * certificate and include the chain of trust in order. This will be returned by + * {@link android.security.KeyChain#getCertificateChain}. + * @param alias The private key alias under which to install the certificate. If a certificate + * with that alias already exists, it will be overwritten. + * @param requestAccess {@code true} to request that the calling app be granted access to the + * credentials immediately. Otherwise, access to the credentials will be gated by user + * approval. + * @param isUserSelectable {@code true} to indicate that a user can select this key via the + * Certificate Selection prompt, false to indicate that this key can only be granted + * access by implementing + * {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias}. + * @return {@code true} if the keys were installed, {@code false} otherwise. + * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile + * owner. + * @see android.security.KeyChain#getCertificateChain + * @see #setDelegatedScopes + * @see #DELEGATION_CERT_INSTALL + */ + public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey, + @NonNull Certificate[] certs, @NonNull String alias, boolean requestAccess, + boolean isUserSelectable) { throwIfParentInstance("installKeyPair"); try { final byte[] pemCert = Credentials.convertToPem(certs[0]); @@ -3868,7 +3909,7 @@ public class DevicePolicyManager { final byte[] pkcs8Key = KeyFactory.getInstance(privKey.getAlgorithm()) .getKeySpec(privKey, PKCS8EncodedKeySpec.class).getEncoded(); return mService.installKeyPair(admin, mContext.getPackageName(), pkcs8Key, pemCert, - pemChain, alias, requestAccess); + pemChain, alias, requestAccess, isUserSelectable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index be0b9205bcdd..b7740e9e7314 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -162,7 +162,8 @@ interface IDevicePolicyManager { boolean isCaCertApproved(in String alias, int userHandle); boolean installKeyPair(in ComponentName who, in String callerPackage, in byte[] privKeyBuffer, - in byte[] certBuffer, in byte[] certChainBuffer, String alias, boolean requestAccess); + in byte[] certBuffer, in byte[] certChainBuffer, String alias, boolean requestAccess, + boolean isUserSelectable); boolean removeKeyPair(in ComponentName who, in String callerPackage, String alias); void choosePrivateKeyAlias(int uid, in Uri uri, in String alias, IBinder aliasCallback); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 2d8a0ee02225..60c36d1b7203 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -4917,7 +4917,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean installKeyPair(ComponentName who, String callerPackage, byte[] privKey, - byte[] cert, byte[] chain, String alias, boolean requestAccess) { + byte[] cert, byte[] chain, String alias, boolean requestAccess, + boolean isUserSelectable) { enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_CERT_INSTALL); @@ -4935,6 +4936,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (requestAccess) { keyChain.setGrant(callingUid, alias, true); } + keyChain.setUserSelectable(alias, isUserSelectable); return true; } catch (RemoteException e) { Log.e(LOG_TAG, "Installing certificate", e); |