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

Commit 6e24576b authored by Brian Carlstrom's avatar Brian Carlstrom Committed by Android (Google) Code Review
Browse files

Merge "KeyChain API for credential installation"

parents 3e622f5c a00a2b33
Loading
Loading
Loading
Loading
+6 −10
Original line number Diff line number Diff line
@@ -21,31 +21,27 @@ import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.jce.netscape.NetscapeCertRequest;
import com.android.org.bouncycastle.util.encoders.Base64;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.security.Credentials;
import android.security.KeyChain;
import android.util.Log;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.HashMap;

class CertTool {
final class CertTool {
    private static final String LOGTAG = "CertTool";

    private static final AlgorithmIdentifier MD5_WITH_RSA =
            new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption);

    static final String CERT = Credentials.CERTIFICATE;
    static final String PKCS12 = Credentials.PKCS12;

    private static HashMap<String, String> sCertificateTypeMap;
    static {
        sCertificateTypeMap = new HashMap<String, String>();
        sCertificateTypeMap.put("application/x-x509-ca-cert", CertTool.CERT);
        sCertificateTypeMap.put("application/x-x509-user-cert", CertTool.CERT);
        sCertificateTypeMap.put("application/x-pkcs12", CertTool.PKCS12);
        sCertificateTypeMap.put("application/x-x509-ca-cert", KeyChain.EXTRA_CERTIFICATE);
        sCertificateTypeMap.put("application/x-x509-user-cert", KeyChain.EXTRA_CERTIFICATE);
        sCertificateTypeMap.put("application/x-pkcs12", KeyChain.EXTRA_PKCS12);
    }

    static String[] getKeyStrengthList() {
+7 −20
Original line number Diff line number Diff line
@@ -60,16 +60,10 @@ public class Credentials {
    public static final String WIFI = "WIFI_";

    /** Data type for public keys. */
    public static final String PUBLIC_KEY = "KEY";
    public static final String EXTRA_PUBLIC_KEY = "KEY";

    /** Data type for private keys. */
    public static final String PRIVATE_KEY = "PKEY";

    /** Data type for certificates. */
    public static final String CERTIFICATE = "CERT";

    /** Data type for PKCS12. */
    public static final String PKCS12 = "PKCS12";
    public static final String EXTRA_PRIVATE_KEY = "PKEY";

    // historically used by Android
    public static final String EXTENSION_CRT = ".crt";
@@ -130,16 +124,9 @@ public class Credentials {
        }
    }

    private Intent createInstallIntent() {
        Intent intent = new Intent(INSTALL_ACTION);
        intent.setClassName("com.android.certinstaller",
                "com.android.certinstaller.CertInstallerMain");
        return intent;
    }

    public void install(Context context) {
        try {
            Intent intent = createInstallIntent();
            Intent intent = KeyChain.createInstallIntent();
            context.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Log.w(LOGTAG, e.toString());
@@ -148,9 +135,9 @@ public class Credentials {

    public void install(Context context, KeyPair pair) {
        try {
            Intent intent = createInstallIntent();
            intent.putExtra(PRIVATE_KEY, pair.getPrivate().getEncoded());
            intent.putExtra(PUBLIC_KEY, pair.getPublic().getEncoded());
            Intent intent = KeyChain.createInstallIntent();
            intent.putExtra(EXTRA_PRIVATE_KEY, pair.getPrivate().getEncoded());
            intent.putExtra(EXTRA_PUBLIC_KEY, pair.getPublic().getEncoded());
            context.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Log.w(LOGTAG, e.toString());
@@ -159,7 +146,7 @@ public class Credentials {

    public void install(Context context, String type, byte[] value) {
        try {
            Intent intent = createInstallIntent();
            Intent intent = KeyChain.createInstallIntent();
            intent.putExtra(type, value);
            context.startActivity(intent);
        } catch (ActivityNotFoundException e) {
+87 −1
Original line number Diff line number Diff line
@@ -89,30 +89,116 @@ public final class KeyChain {
    public static final String ACCOUNT_TYPE = "com.android.keychain";

    /**
     * Action to bring up the KeyChainActivity
     */
    private static final String ACTION_CHOOSER = "com.android.keychain.CHOOSER";

    /**
     * Extra for use with {@link #ACTION_CHOOSER}
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_RESPONSE = "response";

    /**
     * Extra for use with {@link #ACTION_CHOOSER}
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_HOST = "host";

    /**
     * Extra for use with {@link #ACTION_CHOOSER}
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_PORT = "port";

    /**
     * Extra for use with {@link #ACTION_CHOOSER}
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_ALIAS = "alias";

    /**
     * Extra for use with {@link #ACTION_CHOOSER}
     * @hide Also used by KeyChainActivity implementation
     */
    public static final String EXTRA_SENDER = "sender";

    /**
     * Action to bring up the CertInstaller
     */
    private static final String ACTION_INSTALL = "android.credentials.INSTALL";

    /**
     * Optional extra to specify a {@code String} credential name on
     * the {@code Intent} returned by {@link #createInstallIntent}.
     *
     * @hide TODO make public
     */
    // Compatible with old com.android.certinstaller.CredentialHelper.CERT_NAME_KEY
    public static final String EXTRA_NAME = "name";

    /**
     * Optional extra to specify an X.509 certificate to install on
     * the {@code Intent} returned by {@link #createInstallIntent}.
     * The extra value should be a PEM or ASN.1 DER encoded {@code
     * byte[]}. An {@link X509Certificate} can be converted to DER
     * encoded bytes with {@link X509Certificate#getEncoded}.
     *
     * <p>{@link #EXTRA_NAME} may be used to provide a default alias
     * name for the installed certificate.
     *
     * @hide TODO make public
     */
    // Compatible with old android.security.Credentials.CERTIFICATE
    public static final String EXTRA_CERTIFICATE = "CERT";

    /**
     * Optional extra for use with the {@code Intent} returned by
     * {@link #createInstallIntent} to specify a PKCS#12 key store to
     * install. The extra value should be a {@code byte[]}. The bytes
     * may come from an external source or be generated with {@link
     * KeyStore#store} on a "PKCS12" instance.
     *
     * <p>The user will be prompted for the password to load the key store.
     *
     * <p>The key store will be scanned for {@link
     * java.security.KeyStore.PrivateKeyEntry} entries and both the
     * private key and associated certificate chain will be installed.
     *
     * <p>{@link #EXTRA_NAME} may be used to provide a default alias
     * name for the installed credentials.
     *
     * @hide TODO make public
     */
    // Compatible with old android.security.Credentials.PKCS12
    public static final String EXTRA_PKCS12 = "PKCS12";

    /**
     * Returns an {@code Intent} that can be used for credential
     * installation. The intent may be used without any extras, in
     * which case the user will be able to install credentials from
     * their own source.
     *
     * <p>Alternatively, {@link #EXTRA_CERTIFICATE} or {@link
     * #EXTRA_PKCS12} maybe used to specify the bytes of an X.509
     * certificate or a PKCS#12 key store for installation. These
     * extras may be combined with {@link EXTRA_NAME} to provide a
     * default alias name for credentials being installed.
     *
     * <p>When used with {@link Activity#startActivityForResult},
     * {@link Activity#RESULT_OK} will be returned if a credential was
     * successfully installed, otherwise {@link
     * Activity#RESULT_CANCELED} will be returned.
     *
     * @hide TODO make public with createInstallIntent, EXTRA_NAME, EXTRA_CERTIFICATE, EXTRA_PKCS12
     */
    public static Intent createInstallIntent() {
        Intent intent = new Intent(ACTION_INSTALL);
        intent.setClassName("com.android.certinstaller",
                            "com.android.certinstaller.CertInstallerMain");
        return intent;
    }

    /**
     * Launches an {@code Activity} for the user to select the alias
     * for a private key and certificate pair for authentication. The
@@ -176,7 +262,7 @@ public final class KeyChain {
        if (response == null) {
            throw new NullPointerException("response == null");
        }
        Intent intent = new Intent("com.android.keychain.CHOOSER");
        Intent intent = new Intent(ACTION_CHOOSER);
        intent.putExtra(EXTRA_RESPONSE, new AliasResponse(activity, response));
        intent.putExtra(EXTRA_HOST, host);
        intent.putExtra(EXTRA_PORT, port);