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

Commit 67c30dfe authored by Brian Carlstrom's avatar Brian Carlstrom
Browse files

Replace KeyChainActivity placeholder UI with more polished dialog (1 of 5)

frameworks/base

    Extended KeyChain.chooserPrivateKeyAlias to allow caller to supply
    preferred choice to be selected in chooser. This allows Email
    settings to highlight the current choice when allowing user to
    change settings.
	keystore/java/android/security/KeyChain.java
	api/current.txt

    Implemented KeyChain functionality to pass host and port
    information to KeyChainActivity for display.
	keystore/java/android/security/KeyChain.java

    KeyChain now sends a PendingIntent as part of the Intent it sends
    to the KeyChainActivity which can be used to identify the caller
    in reliable way.
	keystore/java/android/security/KeyChain.java

    Moved .pfx/.p12/.cer/.crt constants to Credentials for reuse.
    Added Credentials.install variant with no value for use from KeyChainActivity
	keystore/java/android/security/Credentials.java

packages/apps/CertInstaller
    Source of extension constants now in Credentials
	src/com/android/certinstaller/CertFile.java

packages/apps/Browser
    Have browser supply host and port information to KeyChain.choosePrivateKeyAlias
    Tracking KeyChain.choosePrivateKeyAlias API change
	src/com/android/browser/Tab.java

packages/apps/Email
    Tracking KeyChain.choosePrivateKeyAlias API change
	src/com/android/email/view/CertificateSelector.java

packages/apps/KeyChain

    KeyChain now depends on bouncycastle X509Name for formatting
    X500Principals, since the 4 X500Principal formatting options could
    not format emailAddress attributes in a human readable way and its
    the most important attribute to display for client certificates in
    most cases.
	Android.mk

    Changing the UI to a dialog, make the activity style transparent.
	AndroidManifest.xml
	res/values/styles.xml

    Layout for chooser dialog
	res/layout/cert_chooser.xml

    Layout for list items in chooser
	res/layout/cert_item.xml

    New resources for dialog including comments for translators.
	res/values/strings.xml

    New dialog based KeyChainActivity. Now also shows requesting app
    and requesting server. Now can preselect a specified alias. New
    link directly to CertInstaller.

	src/com/android/keychain/KeyChainActivity.java

    Fix KeyChainTestActivity to work with TestKeyStore changes that
    were causing network activity on the UI to look up the name of
    localhost. Also track KeyChain.choosePrivateKeyAlias API change.

	tests/src/com/android/keychain/tests/KeyChainTestActivity.java

Change-Id: I07128fba8750f9a6bcb9c6be5da04df992403d69
parent dde052f4
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -17494,7 +17494,7 @@ package android.security {
  public final class KeyChain {
  public final class KeyChain {
    ctor public KeyChain();
    ctor public KeyChain();
    method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int);
    method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
    method public static java.security.cert.X509Certificate[] getCertificateChain(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
    method public static java.security.cert.X509Certificate[] getCertificateChain(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
    method public static java.security.PrivateKey getPrivateKey(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
    method public static java.security.PrivateKey getPrivateKey(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
  }
  }
+16 −0
Original line number Original line Diff line number Diff line
@@ -71,6 +71,13 @@ public class Credentials {
    /** Data type for PKCS12. */
    /** Data type for PKCS12. */
    public static final String PKCS12 = "PKCS12";
    public static final String PKCS12 = "PKCS12";


    // historically used by Android
    public static final String EXTENSION_CRT = ".crt";
    public static final String EXTENSION_P12 = ".p12";
    // commonly used on Windows
    public static final String EXTENSION_CER = ".cer";
    public static final String EXTENSION_PFX = ".pfx";

    /**
    /**
     * Convert objects to a PEM format, which is used for
     * Convert objects to a PEM format, which is used for
     * CA_CERTIFICATE, USER_CERTIFICATE, and USER_PRIVATE_KEY
     * CA_CERTIFICATE, USER_CERTIFICATE, and USER_PRIVATE_KEY
@@ -130,6 +137,15 @@ public class Credentials {
        return intent;
        return intent;
    }
    }


    public void install(Context context) {
        try {
            Intent intent = createInstallIntent();
            context.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Log.w(LOGTAG, e.toString());
        }
    }

    public void install(Context context, KeyPair pair) {
    public void install(Context context, KeyPair pair) {
        try {
        try {
            Intent intent = createInstallIntent();
            Intent intent = createInstallIntent();
+36 −9
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
@@ -92,6 +93,26 @@ public final class KeyChain {
     */
     */
    public static final String EXTRA_RESPONSE = "response";
    public static final String EXTRA_RESPONSE = "response";


    /**
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_HOST = "host";

    /**
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_PORT = "port";

    /**
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_ALIAS = "alias";

    /**
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_SENDER = "sender";

    /**
    /**
     * Launches an {@code Activity} for the user to select the alias
     * Launches an {@code Activity} for the user to select the alias
     * for a private key and certificate pair for authentication. The
     * for a private key and certificate pair for authentication. The
@@ -106,6 +127,9 @@ public final class KeyChain {
     * <p>{@code host} and {@code port} may be used to give the user
     * <p>{@code host} and {@code port} may be used to give the user
     * more context about the server requesting the credentials.
     * more context about the server requesting the credentials.
     *
     *
     * <p>{@code alias} allows the chooser to preselect an existing
     * alias which will still be subject to user confirmation.
     *
     * <p>This method requires the caller to hold the permission
     * <p>This method requires the caller to hold the permission
     * {@link android.Manifest.permission#USE_CREDENTIALS}.
     * {@link android.Manifest.permission#USE_CREDENTIALS}.
     *
     *
@@ -123,14 +147,17 @@ public final class KeyChain {
     *     certificate, or null if unavailable.
     *     certificate, or null if unavailable.
     * @param port The port number of the server requesting the
     * @param port The port number of the server requesting the
     *     certificate, or -1 if unavailable.
     *     certificate, or -1 if unavailable.
     * @param alias The alias to preselect if available, or null if
     *     unavailable.
     */
     */
    public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
    public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
                                             String[] keyTypes, Principal[] issuers,
                                             String[] keyTypes, Principal[] issuers,
                                             String host, int port) {
                                             String host, int port,
                                             String alias) {
        /*
        /*
         * TODO currently keyTypes, issuers, host, and port are
         * TODO currently keyTypes, issuers are unused. They are meant
         * unused. They are meant to follow the semantics and purpose
         * to follow the semantics and purpose of X509KeyManager
         * of X509KeyManager method arguments.
         * method arguments.
         *
         *
         * keyTypes would allow the list to be filtered and typically
         * keyTypes would allow the list to be filtered and typically
         * will be set correctly by the server. In practice today,
         * will be set correctly by the server. In practice today,
@@ -142,11 +169,6 @@ public final class KeyChain {
         * server. Others will send none. If this is used, if there
         * server. Others will send none. If this is used, if there
         * are no matches after applying the constraint, it should be
         * are no matches after applying the constraint, it should be
         * ignored.
         * ignored.
         *
         * host and port may be shown to the user if available, but it
         * should be clear that they are not validated values, perhaps
         * shown along with requesting application identity to clarify
         * the source of the request.
         */
         */
        if (activity == null) {
        if (activity == null) {
            throw new NullPointerException("activity == null");
            throw new NullPointerException("activity == null");
@@ -156,6 +178,11 @@ public final class KeyChain {
        }
        }
        Intent intent = new Intent("com.android.keychain.CHOOSER");
        Intent intent = new Intent("com.android.keychain.CHOOSER");
        intent.putExtra(EXTRA_RESPONSE, new AliasResponse(activity, response));
        intent.putExtra(EXTRA_RESPONSE, new AliasResponse(activity, response));
        intent.putExtra(EXTRA_HOST, host);
        intent.putExtra(EXTRA_PORT, port);
        intent.putExtra(EXTRA_ALIAS, alias);
        // the PendingIntent is used to get calling package name
        intent.putExtra(EXTRA_SENDER, PendingIntent.getActivity(activity, 0, new Intent(), 0));
        activity.startActivity(intent);
        activity.startActivity(intent);
    }
    }