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

Commit 484d8bd7 authored by Robin Lee's avatar Robin Lee Committed by Android (Google) Code Review
Browse files

Merge "Add DevicePolicyManager PrivateKey mgmt" into lmp-dev

parents 1308c4b8 26408ccd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5453,6 +5453,7 @@ package android.app.admin {
    method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
    method public boolean hasGrantedPolicy(android.content.ComponentName, int);
    method public boolean installCaCert(android.content.ComponentName, byte[]);
    method public void installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
    method public boolean isActivePasswordSufficient();
    method public boolean isAdminActive(android.content.ComponentName);
    method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
+29 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.security.Credentials;
import android.service.restrictions.RestrictionsReceiver;
import android.util.Log;

@@ -49,6 +50,8 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -1837,6 +1840,32 @@ public class DevicePolicyManager {
        return false;
    }

    /**
     * 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 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
     * with that alias already exists, it will be overwritten.
     * @return {@code true} if the keys were installed, {@code false} otherwise.
     */
    public boolean installKeyPair(ComponentName who, PrivateKey privKey, Certificate cert,
            String alias) {
        try {
            final byte[] pemCert = Credentials.convertToPem(cert);
            return mService.installKeyPair(who, privKey.getEncoded(), pemCert, alias);
        } catch (CertificateException e) {
            Log.w(TAG, "Error encoding certificate", e);
        } catch (IOException e) {
            Log.w(TAG, "Error writing certificate", e);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed talking with device policy service", e);
        }
        return false;
    }

    /**
     * Returns the alias of a given CA certificate in the certificate store, or null if it
     * doesn't exist.
+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@ interface IDevicePolicyManager {
    void uninstallCaCert(in ComponentName admin, in String alias);
    void enforceCanManageCaCerts(in ComponentName admin);

    boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias);

    void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
    void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);

+3 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ interface IKeyChainService {
    // APIs used by CertInstaller
    void installCaCertificate(in byte[] caCertificate);

    // APIs used by DevicePolicyManager
    boolean installKeyPair(in byte[] privateKey, in byte[] userCert, String alias);

    // APIs used by Settings
    boolean deleteCaCertificate(String alias);
    boolean reset();
+34 −3
Original line number Diff line number Diff line
@@ -44,13 +44,13 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.usb.UsbManager;
import android.media.AudioManager;
import android.media.IAudioService;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.database.ContentObserver;
import android.hardware.usb.UsbManager;
import android.net.ProxyInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -69,6 +69,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.security.Credentials;
import android.security.IKeyChainService;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
import android.util.Log;
@@ -110,6 +111,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -2829,6 +2831,35 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }
    }

    @Override
    public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) {
        if (who == null) {
            throw new NullPointerException("ComponentName is null");
        }
        synchronized (this) {
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
        }
        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
        final long id = Binder.clearCallingIdentity();
        try {
          final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
          try {
              IKeyChainService keyChain = keyChainConnection.getService();
              return keyChain.installKeyPair(privKey, cert, alias);
          } catch (RemoteException e) {
              Log.e(LOG_TAG, "Installing certificate", e);
          } finally {
              keyChainConnection.close();
          }
        } catch (InterruptedException e) {
            Log.w(LOG_TAG, "Interrupted while installing certificate", e);
            Thread.currentThread().interrupt();
        } finally {
            Binder.restoreCallingIdentity(id);
        }
        return false;
    }

    void wipeDataLocked(int flags) {
        // If the SD card is encrypted and non-removable, we have to force a wipe.
        boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();