Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7682e5d1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "DPM: Add API for granting apps access to keys"

parents 99143484 49ed3232
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6794,6 +6794,7 @@ package android.app.admin {
    method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String);
    method public void setGlobalSetting(@NonNull android.content.ComponentName, String, String);
    method public void setKeepUninstalledPackages(@Nullable android.content.ComponentName, @NonNull java.util.List<java.lang.String>);
    method public boolean setKeyGrantForApp(@Nullable android.content.ComponentName, @NonNull String, @NonNull String, boolean);
    method public boolean setKeyPairCertificate(@Nullable android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.security.cert.Certificate>, boolean);
    method public boolean setKeyguardDisabled(@NonNull android.content.ComponentName, boolean);
    method public void setKeyguardDisabledFeatures(@NonNull android.content.ComponentName, int);
+36 −0
Original line number Diff line number Diff line
@@ -4981,6 +4981,42 @@ public class DevicePolicyManager {
        return null;
    }


    /**
     * Called by a device or profile owner, or delegated certificate chooser (an app that has been
     * delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to grant an application access
     * to an already-installed (or generated) KeyChain key.
     * This is useful (in combination with {@link #installKeyPair} or {@link #generateKeyPair}) to
     * let an application call {@link android.security.KeyChain#getPrivateKey} without having to
     * call {@link android.security.KeyChain#choosePrivateKeyAlias} first.
     *
     * The grantee app will receive the {@link android.security.KeyChain#ACTION_KEY_ACCESS_CHANGED}
     * broadcast when access to a key is granted or revoked.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
     *        {@code null} if calling from a delegated certificate installer.
     * @param alias The alias of the key to grant access to.
     * @param packageName The name of the (already installed) package to grant access to.
     * @param hasGrant Whether to grant access to the alias or revoke it.
     * @return {@code true} if the grant was set successfully, {@code false} otherwise.
     *
     * @throws SecurityException if the caller is not a device owner, a profile  owner or
     *         delegated certificate chooser.
     * @throws IllegalArgumentException if {@code packageName} or {@code alias} are empty, or if
     *         {@code packageName} is not a name of an installed package.
     */
    public boolean setKeyGrantForApp(@Nullable ComponentName admin, @NonNull String alias,
            @NonNull String packageName, boolean hasGrant) {
        throwIfParentInstance("addKeyGrant");
        try {
            return mService.setKeyGrantForApp(
                    admin, mContext.getPackageName(), alias, packageName, hasGrant);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }

    /**
     * Returns {@code true} if the device supports attestation of device identifiers in addition
     * to key attestation.
+2 −0
Original line number Diff line number Diff line
@@ -436,4 +436,6 @@ interface IDevicePolicyManager {
    boolean isUnattendedManagedKiosk();

    boolean startViewCalendarEventInManagedProfile(String packageName, long eventId, long start, long end, boolean allDay, int flags);

    boolean setKeyGrantForApp(in ComponentName admin, String callerPackage, String alias, String packageName, boolean hasGrant);
}
+6 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.server.devicepolicy;

import android.app.admin.IDevicePolicyManager;
import android.content.ComponentName;

import com.android.server.SystemService;

@@ -56,4 +57,9 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {

    public void clearSystemUpdatePolicyFreezePeriodRecord() {
    }

    public boolean setKeyGrantForApp(ComponentName admin, String callerPackage, String alias,
            String packageName, boolean hasGrant) {
        return false;
    }
}
+53 −0
Original line number Diff line number Diff line
@@ -5727,6 +5727,59 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        return false;
    }
    @Override
    public boolean setKeyGrantForApp(
            ComponentName who, String callerPackage, String alias, String packageName,
            boolean hasGrant) {
        enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER,
                DELEGATION_CERT_SELECTION);
        if (TextUtils.isEmpty(alias)) {
            throw new IllegalArgumentException("Alias to grant cannot be empty.");
        }
        if (TextUtils.isEmpty(packageName)) {
            throw new IllegalArgumentException("Package to grant to cannot be empty.");
        }
        final int userId = mInjector.userHandleGetCallingUserId();
        final int granteeUid;
        try {
            ApplicationInfo ai = mInjector.getIPackageManager().getApplicationInfo(
                    packageName, 0, userId);
            if (ai == null) {
                throw new IllegalArgumentException(
                        String.format("Provided package %s is not installed", packageName));
            }
            granteeUid = ai.uid;
        } catch (RemoteException e) {
            throw new IllegalStateException("Failure getting grantee uid", e);
        }
        final int callingUid = mInjector.binderGetCallingUid();
        final long id = mInjector.binderClearCallingIdentity();
        try {
            final KeyChainConnection keyChainConnection =
                    KeyChain.bindAsUser(mContext, UserHandle.getUserHandleForUid(callingUid));
            try {
                IKeyChainService keyChain = keyChainConnection.getService();
                keyChain.setGrant(granteeUid, alias, hasGrant);
                return true;
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Setting grant for package.", e);
                return  false;
            } finally {
                keyChainConnection.close();
            }
        } catch (InterruptedException e) {
            Log.w(LOG_TAG, "Interrupted while setting key grant", e);
            Thread.currentThread().interrupt();
        } finally {
            mInjector.binderRestoreCallingIdentity(id);
        }
        return false;
    }
    /**
     * Enforce one the following conditions are met:
     * (1) The device has a Device Owner, and one of the following holds: