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

Commit bf528538 authored by Pavel Grafov's avatar Pavel Grafov
Browse files

DPM API to grant keys to Wifi

Bug: 160457441
Test: atest com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testKeyManagement
Test: atest com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testDelegatedCertInstallerDirectly
Change-Id: I3a8be9de738ffcc7732e8a640bf42220ab340501
parent 7e3f7d10
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -7112,6 +7112,7 @@ package android.app.admin {
    method @NonNull public android.os.Bundle getUserRestrictions(@NonNull android.content.ComponentName);
    method @Nullable public String getWifiMacAddress(@NonNull android.content.ComponentName);
    method public boolean grantKeyPairToApp(@Nullable android.content.ComponentName, @NonNull String, @NonNull String);
    method public boolean grantKeyPairToWifiAuth(@NonNull String);
    method public boolean hasCaCertInstalled(@Nullable android.content.ComponentName, byte[]);
    method public boolean hasGrantedPolicy(@NonNull android.content.ComponentName, int);
    method public boolean hasKeyPair(@NonNull String);
@@ -7134,6 +7135,7 @@ package android.app.admin {
    method public boolean isDeviceIdAttestationSupported();
    method public boolean isDeviceOwnerApp(String);
    method public boolean isEphemeralUser(@NonNull android.content.ComponentName);
    method public boolean isKeyPairGrantedToWifiAuth(@NonNull String);
    method public boolean isLockTaskPermitted(String);
    method public boolean isLogoutEnabled();
    method public boolean isManagedProfile(@NonNull android.content.ComponentName);
@@ -7169,6 +7171,7 @@ package android.app.admin {
    method @Nullable public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrievePreRebootSecurityLogs(@NonNull android.content.ComponentName);
    method @Nullable public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrieveSecurityLogs(@NonNull android.content.ComponentName);
    method public boolean revokeKeyPairFromApp(@Nullable android.content.ComponentName, @NonNull String, @NonNull String);
    method public boolean revokeKeyPairFromWifiAuth(@NonNull String);
    method public void setAccountManagementDisabled(@NonNull android.content.ComponentName, String, boolean);
    method public void setAffiliationIds(@NonNull android.content.ComponentName, @NonNull java.util.Set<java.lang.String>);
    method public void setAlwaysOnVpnPackage(@NonNull android.content.ComponentName, @Nullable String, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
+68 −0
Original line number Diff line number Diff line
@@ -6436,6 +6436,74 @@ public class DevicePolicyManager {
        return false;
    }
    /**
     * Called by a device or profile owner, or delegated certificate chooser (an app that has been
     * delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to allow using a KeyChain key
     * pair for authentication to Wifi networks. The key can then be used in configurations passed
     * to {@link android.net.wifi.WifiManager#addNetwork}.
     *
     * @param alias The alias of the key pair.
     * @return {@code true} if the operation was set successfully, {@code false} otherwise.
     *
     * @throws SecurityException if the caller is not a device owner, a profile owner or
     *         delegated certificate chooser.
     * @see #revokeKeyPairFromWifiAuth
     */
    public boolean grantKeyPairToWifiAuth(@NonNull String alias) {
        throwIfParentInstance("grantKeyPairToWifiAuth");
        try {
            return mService.setKeyGrantToWifiAuth(mContext.getPackageName(), alias, true);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }
    /**
     * Called by a device or profile owner, or delegated certificate chooser (an app that has been
     * delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to deny using a KeyChain key
     * pair for authentication to Wifi networks. Configured networks using this key won't be able to
     * authenticate.
     *
     * @param alias The alias of the key pair.
     * @return {@code true} if the operation was set successfully, {@code false} otherwise.
     *
     * @throws SecurityException if the caller is not a device owner, a profile owner or
     *         delegated certificate chooser.
     * @see #grantKeyPairToWifiAuth
     */
    public boolean revokeKeyPairFromWifiAuth(@NonNull String alias) {
        throwIfParentInstance("revokeKeyPairFromWifiAuth");
        try {
            return mService.setKeyGrantToWifiAuth(mContext.getPackageName(), alias, false);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }
    /**
     * Called by a device or profile owner, or delegated certificate chooser (an app that has been
     * delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to query whether a KeyChain key
     * pair can be used for authentication to Wifi networks.
     *
     * @param alias The alias of the key pair.
     * @return {@code true} if the key pair can be used, {@code false} otherwise.
     *
     * @throws SecurityException if the caller is not a device owner, a profile owner or
     *         delegated certificate chooser.
     * @see #grantKeyPairToWifiAuth
     */
    public boolean isKeyPairGrantedToWifiAuth(@NonNull String alias) {
        throwIfParentInstance("isKeyPairGrantedToWifiAuth");
        try {
            return mService.isKeyPairGrantedToWifiAuth(mContext.getPackageName(), alias);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }
    /**
     * Returns {@code true} if the device supports attestation of device identifiers in addition
     * to key attestation. See
+2 −0
Original line number Diff line number Diff line
@@ -479,6 +479,8 @@ interface IDevicePolicyManager {

    boolean setKeyGrantForApp(in ComponentName admin, String callerPackage, String alias, String packageName, boolean hasGrant);
    List<String> getKeyPairGrants(in String callerPackage, in String alias);
    boolean setKeyGrantToWifiAuth(String callerPackage, String alias, boolean hasGrant);
    boolean isKeyPairGrantedToWifiAuth(String callerPackage, String alias);

    void setUserControlDisabledPackages(in ComponentName admin, in List<String> packages);

+10 −0
Original line number Diff line number Diff line
@@ -143,4 +143,14 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
    public boolean canAdminGrantSensorsPermissionsForUser(int userId) {
        return false;
    }

    @Override
    public boolean setKeyGrantToWifiAuth(String callerPackage, String alias, boolean hasGrant) {
        return false;
    }

    @Override
    public boolean isKeyPairGrantedToWifiAuth(String callerPackage, String alias) {
        return false;
    }
}
+44 −6
Original line number Diff line number Diff line
@@ -5457,6 +5457,42 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                || isCallerDelegate(caller, DELEGATION_CERT_INSTALL);
    }
    @Override
    public boolean setKeyGrantToWifiAuth(String callerPackage, String alias, boolean hasGrant) {
        Preconditions.checkStringNotEmpty(alias, "Alias to grant cannot be empty");
        final CallerIdentity caller = getCallerIdentity(callerPackage);
        Preconditions.checkCallAuthorization(canManageCertificates(caller));
        return setKeyChainGrantInternal(alias, hasGrant, Process.WIFI_UID, caller.getUserHandle());
    }
    @Override
    public boolean isKeyPairGrantedToWifiAuth(String callerPackage, String alias) {
        Preconditions.checkStringNotEmpty(alias, "Alias to check cannot be empty");
        final CallerIdentity caller = getCallerIdentity(callerPackage);
        Preconditions.checkCallAuthorization(canManageCertificates(caller));
        return mInjector.binderWithCleanCallingIdentity(() -> {
            try (KeyChainConnection keyChainConnection =
                         KeyChain.bindAsUser(mContext, caller.getUserHandle())) {
                final List<String> result = new ArrayList<>();
                final int[] granteeUids = keyChainConnection.getService().getGrants(alias);
                for (final int uid : granteeUids) {
                    if (uid == Process.WIFI_UID) {
                        return true;
                    }
                }
                return false;
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Querying grant to wifi auth.    ", e);
                return false;
            }
        });
    }
    @Override
    public boolean setKeyGrantForApp(ComponentName who, String callerPackage, String alias,
            String packageName, boolean hasGrant) {
@@ -5479,19 +5515,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            throw new IllegalStateException("Failure getting grantee uid", e);
        }
        return setKeyChainGrantInternal(alias, hasGrant, granteeUid, caller.getUserHandle());
    }
    private boolean setKeyChainGrantInternal(String alias, boolean hasGrant, int granteeUid,
            UserHandle userHandle) {
        final long id = mInjector.binderClearCallingIdentity();
        try {
            final KeyChainConnection keyChainConnection =
                    KeyChain.bindAsUser(mContext, caller.getUserHandle());
            try {
            try (KeyChainConnection keyChainConnection =
                         KeyChain.bindAsUser(mContext, userHandle)) {
                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);