diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 26b1b36fa7bfa..88b1f2d702652 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2209,7 +2209,8 @@ public class DevicePolicyManager {
* Called by a device or profile owner to install a certificate and private key pair. The
* keypair will be visible to all apps within the profile.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param who Which {@link DeviceAdminReceiver} this request is associated with. Use
+ * null if calling from a delegated certificate installer.
* @param privKey The private key to install.
* @param cert The certificate to install.
* @param alias The private key alias under which to install the certificate. If a certificate
@@ -2246,9 +2247,9 @@ public class DevicePolicyManager {
/**
* Called by a profile owner or device owner to grant access to privileged certificate
- * manipulation APIs to a third-party CA certificate installer app. Granted APIs include
+ * manipulation APIs to a third-party certificate installer app. Granted APIs include
* {@link #getInstalledCaCerts}, {@link #hasCaCertInstalled}, {@link #installCaCert},
- * {@link #uninstallCaCert} and {@link #uninstallAllUserCaCerts}.
+ * {@link #uninstallCaCert}, {@link #uninstallAllUserCaCerts} and {@link #installKeyPair}.
*
* Delegated certificate installer is a per-user state. The delegated access is persistent until * it is later cleared by calling this method with a null value or uninstallling the certificate diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index c500d798e0c69..3677132ae08d3 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -3027,9 +3027,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) { - Preconditions.checkNotNull(who, "ComponentName is null"); - synchronized (this) { - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + if (who == null) { + if (!isCallerDelegatedCertInstaller()) { + throw new SecurityException("who == null, but caller is not cert installer"); + } + } else { + synchronized (this) { + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + } } final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); final long id = Binder.clearCallingIdentity();