/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.security;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.WorkerThread;
import android.app.Activity;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;

import com.android.org.conscrypt.TrustedCertificateStore;

import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.Serializable;
import java.security.KeyPair;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

import javax.security.auth.x500.X500Principal;

/**
 * The {@code KeyChain} class provides access to private keys and
 * their corresponding certificate chains in credential storage.
 *
 * <p>Applications accessing the {@code KeyChain} normally go through
 * these steps:
 *
 * <ol>
 *
 * <li>Receive a callback from an {@link javax.net.ssl.X509KeyManager
 * X509KeyManager} that a private key is requested.
 *
 * <li>Call {@link #choosePrivateKeyAlias
 * choosePrivateKeyAlias} to allow the user to select from a
 * list of currently available private keys and corresponding
 * certificate chains. The chosen alias will be returned by the
 * callback {@link KeyChainAliasCallback#alias}, or null if no private
 * key is available or the user cancels the request.
 *
 * <li>Call {@link #getPrivateKey} and {@link #getCertificateChain} to
 * retrieve the credentials to return to the corresponding {@link
 * javax.net.ssl.X509KeyManager} callbacks.
 *
 * </ol>
 *
 * <p>An application may remember the value of a selected alias to
 * avoid prompting the user with {@link #choosePrivateKeyAlias
 * choosePrivateKeyAlias} on subsequent connections. If the alias is
 * no longer valid, null will be returned on lookups using that value
 *
 * <p>An application can request the installation of private keys and
 * certificates via the {@code Intent} provided by {@link
 * #createInstallIntent}. Private keys installed via this {@code
 * Intent} will be accessible via {@link #choosePrivateKeyAlias} while
 * Certificate Authority (CA) certificates will be trusted by all
 * applications through the default {@code X509TrustManager}.
 */
// TODO reference intent for credential installation when public
public final class KeyChain {

    /**
     * @hide Also used by KeyChainService implementation
     */
    public static final String ACCOUNT_TYPE = "com.android.keychain";

    /**
     * Package name for KeyChain chooser.
     */
    private static final String KEYCHAIN_PACKAGE = "com.android.keychain";

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

    /**
     * Package name for the Certificate Installer.
     */
    private static final String CERT_INSTALLER_PACKAGE = "com.android.certinstaller";

    /**
     * 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_URI = "uri";

    /**
     * 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";

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

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

    /**
     * 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}.
     */
    // 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.
     */
    // 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
     * java.security.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.
     */
    // Compatible with old android.security.Credentials.PKCS12
    public static final String EXTRA_PKCS12 = "PKCS12";

    /**
     * Broadcast Action: Indicates the trusted storage has changed. Sent when
     * one of this happens:
     *
     * <ul>
     * <li>a new CA is added,
     * <li>an existing CA is removed or disabled,
     * <li>a disabled CA is enabled,
     * <li>trusted storage is reset (all user certs are cleared),
     * <li>when permission to access a private key is changed.
     * </ul>
     *
     * @deprecated Use {@link #ACTION_KEYCHAIN_CHANGED}, {@link #ACTION_TRUST_STORE_CHANGED} or
     * {@link #ACTION_KEY_ACCESS_CHANGED}. Apps that target a version higher than
     * {@link android.os.Build.VERSION_CODES#N_MR1} will only receive this broadcast if they
     * register for it at runtime.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_STORAGE_CHANGED = "android.security.STORAGE_CHANGED";

    /**
     * Broadcast Action: Indicates the contents of the keychain has changed. Sent when a KeyChain
     * entry is added, modified or removed.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_KEYCHAIN_CHANGED = "android.security.action.KEYCHAIN_CHANGED";

    /**
     * Broadcast Action: Indicates the contents of the trusted certificate store has changed. Sent
     * when one the following occurs:
     *
     * <ul>
     * <li>A pre-installed CA is disabled or re-enabled</li>
     * <li>A CA is added or removed from the trust store</li>
     * </ul>
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_TRUST_STORE_CHANGED =
            "android.security.action.TRUST_STORE_CHANGED";

    /**
     * Broadcast Action: Indicates that the access permissions for a private key have changed.
     *
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_KEY_ACCESS_CHANGED =
            "android.security.action.KEY_ACCESS_CHANGED";

    /**
     * Used as a String extra field in {@link #ACTION_KEY_ACCESS_CHANGED} to supply the alias of
     * the key.
     */
    public static final String EXTRA_KEY_ALIAS = "android.security.extra.KEY_ALIAS";

    /**
     * Used as a boolean extra field in {@link #ACTION_KEY_ACCESS_CHANGED} to supply if the key is
     * accessible to the application.
     */
    public static final String EXTRA_KEY_ACCESSIBLE = "android.security.extra.KEY_ACCESSIBLE";

    /**
     * Indicates that a call to {@link #generateKeyPair} was successful.
     * @hide
     */
    public static final int KEY_GEN_SUCCESS = 0;

    /**
     * An alias was missing from the key specifications when calling {@link #generateKeyPair}.
     * @hide
     */
    public static final int KEY_GEN_MISSING_ALIAS = 1;

    /**
     * A key attestation challenge was provided to {@link #generateKeyPair}, but it shouldn't
     * have been provided.
     * @hide
     */
    public static final int KEY_GEN_SUPERFLUOUS_ATTESTATION_CHALLENGE = 2;

    /**
     * Algorithm not supported by {@link #generateKeyPair}
     * @hide
     */
    public static final int KEY_GEN_NO_SUCH_ALGORITHM = 3;

    /**
     * Invalid algorithm parameters when calling {@link #generateKeyPair}
     * @hide
     */
    public static final int KEY_GEN_INVALID_ALGORITHM_PARAMETERS = 4;

    /**
     * Keystore is not available when calling {@link #generateKeyPair}
     * @hide
     */
    public static final int KEY_GEN_NO_KEYSTORE_PROVIDER = 5;

    /**
     * StrongBox unavailable when calling {@link #generateKeyPair}
     * @hide
     */
    public static final int KEY_GEN_STRONGBOX_UNAVAILABLE = 6;

    /**
     * General failure while calling {@link #generateKeyPair}
     * @hide
     */
    public static final int KEY_GEN_FAILURE = 7;

    /**
     * Successful call to {@link #attestKey}
     * @hide
     */
    public static final int KEY_ATTESTATION_SUCCESS = 0;

    /**
     * Attestation challenge missing when calling {@link #attestKey}
     * @hide
     */
    public static final int KEY_ATTESTATION_MISSING_CHALLENGE = 1;

    /**
     * The caller requested Device ID attestation when calling {@link #attestKey}, but has no
     * permissions to get device identifiers.
     * @hide
     */
    public static final int KEY_ATTESTATION_CANNOT_COLLECT_DATA = 2;

    /**
     * The underlying hardware does not support Device ID attestation or cannot attest to the
     * identifiers that are stored on the device. This indicates permanent inability
     * to get attestation records on the device.
     * @hide
     */
    public static final int KEY_ATTESTATION_CANNOT_ATTEST_IDS = 3;

    /**
     * General failure when calling {@link #attestKey}
     * @hide
     */
    public static final int KEY_ATTESTATION_FAILURE = 4;

    /**
     * Used by DPC or delegated app in
     * {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias} or
     * {@link android.app.admin.DelegatedAdminReceiver#onChoosePrivateKeyAlias} to identify that
     * the requesting app is not granted access to any key, and nor will the user be able to grant
     * access manually.
     */
    public static final String KEY_ALIAS_SELECTION_DENIED =
            "android:alias-selection-denied";

    /**
     * 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.
     */
    @NonNull
    public static Intent createInstallIntent() {
        Intent intent = new Intent(ACTION_INSTALL);
        intent.setClassName(CERT_INSTALLER_PACKAGE,
                            "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
     * selected alias or null will be returned via the
     * KeyChainAliasCallback callback.
     *
     * <p>A device policy controller (as a device or profile owner) can
     * intercept the request before the activity is shown, to pick a
     * specific private key alias by implementing
     * {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias
     * onChoosePrivateKeyAlias}.
     *
     * <p>{@code keyTypes} and {@code issuers} may be used to
     * narrow down suggested choices to the user. If either {@code keyTypes}
     * or {@code issuers} is specified and non-empty, and there are no
     * matching certificates in the KeyChain, then the certificate
     * selection prompt would be suppressed entirely.
     *
     * <p>{@code host} and {@code port} may be used to give the user
     * more context about the server requesting the credentials.
     *
     * <p>{@code alias} allows the caller to preselect an existing
     * alias which will still be subject to user confirmation.
     *
     * @param activity The {@link Activity} context to use for
     *     launching the new sub-Activity to prompt the user to select
     *     a private key; used only to call startActivity(); must not
     *     be null.
     * @param response Callback to invoke when the request completes;
     *     must not be null.
     * @param keyTypes The acceptable types of asymmetric keys such as
     *     "RSA", "EC" or null.
     * @param issuers The acceptable certificate issuers for the
     *     certificate matching the private key, or null.
     * @param host The host name of the server requesting the
     *     certificate, or null if unavailable.
     * @param port The port number of the server requesting the
     *     certificate, or -1 if unavailable.
     * @param alias The alias to preselect if available, or null if
     *     unavailable.
     */
    public static void choosePrivateKeyAlias(@NonNull Activity activity,
            @NonNull KeyChainAliasCallback response,
            @Nullable @KeyProperties.KeyAlgorithmEnum String[] keyTypes,
            @Nullable Principal[] issuers,
            @Nullable String host, int port, @Nullable String alias) {
        Uri uri = null;
        if (host != null) {
            uri = new Uri.Builder()
                    .authority(host + (port != -1 ? ":" + port : ""))
                    .build();
        }
        choosePrivateKeyAlias(activity, response, keyTypes, issuers, uri, alias);
    }

    /**
     * Launches an {@code Activity} for the user to select the alias
     * for a private key and certificate pair for authentication. The
     * selected alias or null will be returned via the
     * KeyChainAliasCallback callback.
     *
     * <p>A device policy controller (as a device or profile owner) can
     * intercept the request before the activity is shown, to pick a
     * specific private key alias by implementing
     * {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias
     * onChoosePrivateKeyAlias}.
     *
     * <p>{@code keyTypes} and {@code issuers} may be used to
     * narrow down suggested choices to the user. If either {@code keyTypes}
     * or {@code issuers} is specified and non-empty, and there are no
     * matching certificates in the KeyChain, then the certificate
     * selection prompt would be suppressed entirely.
     *
     * <p>{@code uri} may be used to give the user more context about
     * the server requesting the credentials.
     *
     * <p>{@code alias} allows the caller to preselect an existing
     * alias which will still be subject to user confirmation.
     *
     * @param activity The {@link Activity} context to use for
     *     launching the new sub-Activity to prompt the user to select
     *     a private key; used only to call startActivity(); must not
     *     be null.
     * @param response Callback to invoke when the request completes;
     *     must not be null.
     * @param keyTypes The acceptable types of asymmetric keys such as
     *     "RSA", "EC" or null.
     * @param issuers The acceptable certificate issuers for the
     *     certificate matching the private key, or null.
     * @param uri The full URI the server is requesting the certificate
     *     for, or null if unavailable.
     * @param alias The alias to preselect if available, or null if
     *     unavailable.
     * @throws IllegalArgumentException if the specified issuers are not
     *     of type {@code X500Principal}.
     */
    public static void choosePrivateKeyAlias(@NonNull Activity activity,
            @NonNull KeyChainAliasCallback response,
            @Nullable @KeyProperties.KeyAlgorithmEnum String[] keyTypes,
            @Nullable Principal[] issuers,
            @Nullable Uri uri, @Nullable String alias) {
        /*
         * Specifying keyTypes excludes certificates with different key types
         * from the list of certificates presented to the user.
         * In practice today, most servers would require RSA or EC
         * certificates.
         *
         * Specifying issuers narrows down the list by filtering out
         * certificates with issuers which are not matching the provided ones.
         * This has been reported to Chrome several times (crbug.com/731769).
         * There's no concrete description on what to do when the client has no
         * certificates that match the provided issuers.
         * To be conservative, Android will not present the user with any
         * certificates to choose from.
         * If the list of issuers is empty then the client may send any
         * certificate, see:
         * https://tools.ietf.org/html/rfc5246#section-7.4.4
         */
        if (activity == null) {
            throw new NullPointerException("activity == null");
        }
        if (response == null) {
            throw new NullPointerException("response == null");
        }
        Intent intent = new Intent(ACTION_CHOOSER);
        intent.setPackage(KEYCHAIN_PACKAGE);
        intent.putExtra(EXTRA_RESPONSE, new AliasResponse(response));
        intent.putExtra(EXTRA_URI, uri);
        intent.putExtra(EXTRA_ALIAS, alias);
        intent.putExtra(EXTRA_KEY_TYPES, keyTypes);
        ArrayList<byte[]> issuersList = new ArrayList();
        if (issuers != null) {
            for (Principal issuer: issuers) {
                // In a TLS client context (like Chrome), issuers would only
                // be specified as X500Principals. No other use cases for
                // specifying principals have been brought up. Under these
                // circumstances, only allow issuers specified as
                // X500Principals.
                if (!(issuer instanceof X500Principal)) {
                    throw new IllegalArgumentException(String.format(
                            "Issuer %s is of type %s, not X500Principal",
                            issuer.toString(), issuer.getClass()));
                }
                // Pass the DER-encoded issuer as that's the most accurate
                // representation and what is sent over the wire.
                issuersList.add(((X500Principal) issuer).getEncoded());
            }
        }
        intent.putExtra(EXTRA_ISSUERS, (Serializable) issuersList);
        // the PendingIntent is used to get calling package name
        intent.putExtra(EXTRA_SENDER, PendingIntent.getActivity(activity, 0, new Intent(), 0));
        activity.startActivity(intent);
    }

    private static class AliasResponse extends IKeyChainAliasCallback.Stub {
        private final KeyChainAliasCallback keyChainAliasResponse;
        private AliasResponse(KeyChainAliasCallback keyChainAliasResponse) {
            this.keyChainAliasResponse = keyChainAliasResponse;
        }
        @Override public void alias(String alias) {
            keyChainAliasResponse.alias(alias);
        }
    }

    /**
     * Returns the {@code PrivateKey} for the requested alias, or null if the alias does not exist
     * or the caller has no permission to access it (see note on exceptions below).
     *
     * <p> This method may block while waiting for a connection to another process, and must never
     * be called from the main thread.
     * <p> As {@link Activity} and {@link Service} contexts are short-lived and can be destroyed
     * at any time from the main thread, it is safer to rely on a long-lived context such as one
     * returned from {@link Context#getApplicationContext()}.
     *
     * <p> If the caller provides a valid alias to which it was not granted access, then the
     * caller must invoke {@link #choosePrivateKeyAlias} again to get another valid alias
     * or a grant to access the same alias.
     * <p>On Android versions prior to Q, when a key associated with the specified alias is
     * unavailable, the method will throw a {@code KeyChainException} rather than return null.
     * If the exception's cause (as obtained by calling {@code KeyChainException.getCause()})
     * is a throwable of type {@code IllegalStateException} then the caller lacks a grant
     * to access the key and certificates associated with this alias.
     *
     * @param alias The alias of the desired private key, typically returned via
     *              {@link KeyChainAliasCallback#alias}.
     * @throws KeyChainException if the alias was valid but there was some problem accessing it.
     * @throws IllegalStateException if called from the main thread.
     */
    @Nullable @WorkerThread
    public static PrivateKey getPrivateKey(@NonNull Context context, @NonNull String alias)
            throws KeyChainException, InterruptedException {
        KeyPair keyPair = getKeyPair(context, alias);
        if (keyPair != null) {
            return keyPair.getPrivate();
        }

        return null;
    }

    /** @hide */
    @Nullable @WorkerThread
    public static KeyPair getKeyPair(@NonNull Context context, @NonNull String alias)
            throws KeyChainException, InterruptedException {
        if (alias == null) {
            throw new NullPointerException("alias == null");
        }
        if (context == null) {
            throw new NullPointerException("context == null");
        }

        final String keyId;
        try (KeyChainConnection keyChainConnection = bind(context.getApplicationContext())) {
            keyId = keyChainConnection.getService().requestPrivateKey(alias);
        } catch (RemoteException e) {
            throw new KeyChainException(e);
        } catch (RuntimeException e) {
            // only certain RuntimeExceptions can be propagated across the IKeyChainService call
            throw new KeyChainException(e);
        }

        if (keyId == null) {
            return null;
        } else {
            try {
                return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
                        KeyStore.getInstance(), keyId, KeyStore.UID_SELF);
            } catch (RuntimeException | UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
                throw new KeyChainException(e);
            }
        }
    }

    /**
     * Returns the {@code X509Certificate} chain for the requested alias, or null if the alias
     * does not exist or the caller has no permission to access it (see note on exceptions
     * in {@link #getPrivateKey}).
     *
     * <p>
     * <strong>Note:</strong> If a certificate chain was explicitly specified when the alias was
     * installed, this method will return that chain. If only the client certificate was specified
     * at the installation time, this method will try to build a certificate chain using all
     * available trust anchors (preinstalled and user-added).
     *
     * <p> This method may block while waiting for a connection to another process, and must never
     * be called from the main thread.
     * <p> As {@link Activity} and {@link Service} contexts are short-lived and can be destroyed
     * at any time from the main thread, it is safer to rely on a long-lived context such as one
     * returned from {@link Context#getApplicationContext()}.
     * <p> In case the caller specifies an alias for which it lacks a grant, it must call
     * {@link #choosePrivateKeyAlias} again. See {@link #getPrivateKey} for more details on
     * coping with this scenario.
     *
     * @param alias The alias of the desired certificate chain, typically
     * returned via {@link KeyChainAliasCallback#alias}.
     * @throws KeyChainException if the alias was valid but there was some problem accessing it.
     * @throws IllegalStateException if called from the main thread.
     */
    @Nullable @WorkerThread
    public static X509Certificate[] getCertificateChain(@NonNull Context context,
            @NonNull String alias) throws KeyChainException, InterruptedException {
        if (alias == null) {
            throw new NullPointerException("alias == null");
        }

        final byte[] certificateBytes;
        final byte[] certChainBytes;
        try (KeyChainConnection keyChainConnection = bind(context.getApplicationContext())) {
            IKeyChainService keyChainService = keyChainConnection.getService();
            certificateBytes = keyChainService.getCertificate(alias);
            if (certificateBytes == null) {
                return null;
            }
            certChainBytes = keyChainService.getCaCertificates(alias);
        } catch (RemoteException e) {
            throw new KeyChainException(e);
        } catch (RuntimeException e) {
            // only certain RuntimeExceptions can be propagated across the IKeyChainService call
            throw new KeyChainException(e);
        }

        try {
            X509Certificate leafCert = toCertificate(certificateBytes);
            // If the keypair is installed with a certificate chain by either
            // DevicePolicyManager.installKeyPair or CertInstaller, return that chain.
            if (certChainBytes != null && certChainBytes.length != 0) {
                Collection<X509Certificate> chain = toCertificates(certChainBytes);
                ArrayList<X509Certificate> fullChain = new ArrayList<>(chain.size() + 1);
                fullChain.add(leafCert);
                fullChain.addAll(chain);
                return fullChain.toArray(new X509Certificate[fullChain.size()]);
            } else {
                // If there isn't a certificate chain, either due to a pre-existing keypair
                // installed before N, or no chain is explicitly installed under the new logic,
                // fall back to old behavior of constructing the chain from trusted credentials.
                //
                // This logic exists to maintain old behaviour for already installed keypair, at
                // the cost of potentially returning extra certificate chain for new clients who
                // explicitly installed only the client certificate without a chain. The latter
                // case is actually no different from pre-N behaviour of getCertificateChain(),
                // in that sense this change introduces no regression. Besides the returned chain
                // is still valid so the consumer of the chain should have no problem verifying it.
                TrustedCertificateStore store = new TrustedCertificateStore();
                List<X509Certificate> chain = store.getCertificateChain(leafCert);
                return chain.toArray(new X509Certificate[chain.size()]);
            }
        } catch (CertificateException | RuntimeException e) {
            throw new KeyChainException(e);
        }
    }

    /**
     * Returns {@code true} if the current device's {@code KeyChain} supports a
     * specific {@code PrivateKey} type indicated by {@code algorithm} (e.g.,
     * "RSA").
     */
    public static boolean isKeyAlgorithmSupported(
            @NonNull @KeyProperties.KeyAlgorithmEnum String algorithm) {
        final String algUpper = algorithm.toUpperCase(Locale.US);
        return KeyProperties.KEY_ALGORITHM_EC.equals(algUpper)
                || KeyProperties.KEY_ALGORITHM_RSA.equals(algUpper);
    }

    /**
     * Returns {@code true} if the current device's {@code KeyChain} binds any
     * {@code PrivateKey} of the given {@code algorithm} to the device once
     * imported or generated. This can be used to tell if there is special
     * hardware support that can be used to bind keys to the device in a way
     * that makes it non-exportable.
     *
     * @deprecated Whether the key is bound to the secure hardware is known only
     * once the key has been imported. To find out, use:
     * <pre>{@code
     * PrivateKey key = ...; // private key from KeyChain
     *
     * KeyFactory keyFactory =
     *     KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
     * KeyInfo keyInfo = keyFactory.getKeySpec(key, KeyInfo.class);
     * if (keyInfo.isInsideSecureHardware()) {
     *     // The key is bound to the secure hardware of this Android
     * }}</pre>
     */
    @Deprecated
    public static boolean isBoundKeyAlgorithm(
            @NonNull @KeyProperties.KeyAlgorithmEnum String algorithm) {
        if (!isKeyAlgorithmSupported(algorithm)) {
            return false;
        }

        return KeyStore.getInstance().isHardwareBacked(algorithm);
    }

    /** @hide */
    @NonNull
    public static X509Certificate toCertificate(@NonNull byte[] bytes) {
        if (bytes == null) {
            throw new IllegalArgumentException("bytes == null");
        }
        try {
            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
            return (X509Certificate) cert;
        } catch (CertificateException e) {
            throw new AssertionError(e);
        }
    }

    /** @hide */
    @NonNull
    public static Collection<X509Certificate> toCertificates(@NonNull byte[] bytes) {
        if (bytes == null) {
            throw new IllegalArgumentException("bytes == null");
        }
        try {
            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            return (Collection<X509Certificate>) certFactory.generateCertificates(
                    new ByteArrayInputStream(bytes));
        } catch (CertificateException e) {
            throw new AssertionError(e);
        }
    }

    /**
     * @hide for reuse by CertInstaller and Settings.
     * @see KeyChain#bind
     */
    public static class KeyChainConnection implements Closeable {
        private final Context mContext;
        private final ServiceConnection mServiceConnection;
        private final IKeyChainService mService;
        protected KeyChainConnection(Context context,
                                     ServiceConnection serviceConnection,
                                     IKeyChainService service) {
            this.mContext = context;
            this.mServiceConnection = serviceConnection;
            this.mService = service;
        }
        @Override public void close() {
            mContext.unbindService(mServiceConnection);
        }

        /** returns the service binder. */
        public IKeyChainService getService() {
            return mService;
        }
    }

    /**
     * Bind to KeyChainService in the current user.
     * Caller should call unbindService on the result when finished.
     *
     *@throws InterruptedException if interrupted during binding.
     *@throws AssertionError if unable to bind to KeyChainService.
     * @hide for reuse by CertInstaller and Settings.
     */
    @WorkerThread
    public static KeyChainConnection bind(@NonNull Context context) throws InterruptedException {
        return bindAsUser(context, Process.myUserHandle());
    }

    /**
     * Bind to KeyChainService in the target user.
     * Caller should call unbindService on the result when finished.
     *
     * @throws InterruptedException if interrupted during binding.
     * @throws AssertionError if unable to bind to KeyChainService.
     * @hide
     */
    @WorkerThread
    public static KeyChainConnection bindAsUser(@NonNull Context context, UserHandle user)
            throws InterruptedException {
        if (context == null) {
            throw new NullPointerException("context == null");
        }
        ensureNotOnMainThread(context);
        final CountDownLatch countDownLatch = new CountDownLatch(1);
        final AtomicReference<IKeyChainService> keyChainService = new AtomicReference<>();
        ServiceConnection keyChainServiceConnection = new ServiceConnection() {
            volatile boolean mConnectedAtLeastOnce = false;
            @Override public void onServiceConnected(ComponentName name, IBinder service) {
                if (!mConnectedAtLeastOnce) {
                    mConnectedAtLeastOnce = true;
                    keyChainService.set(
                            IKeyChainService.Stub.asInterface(Binder.allowBlocking(service)));
                    countDownLatch.countDown();
                }
            }
            @Override public void onBindingDied(ComponentName name) {
                if (!mConnectedAtLeastOnce) {
                    mConnectedAtLeastOnce = true;
                    countDownLatch.countDown();
                }
            }
            @Override public void onServiceDisconnected(ComponentName name) {}
        };
        Intent intent = new Intent(IKeyChainService.class.getName());
        ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
        intent.setComponent(comp);
        if (comp == null || !context.bindServiceAsUser(
                intent, keyChainServiceConnection, Context.BIND_AUTO_CREATE, user)) {
            throw new AssertionError("could not bind to KeyChainService");
        }
        countDownLatch.await();
        IKeyChainService service = keyChainService.get();
        if (service != null) {
            return new KeyChainConnection(context, keyChainServiceConnection, service);
        } else {
            context.unbindService(keyChainServiceConnection);
            throw new AssertionError("KeyChainService died while binding");
        }
    }

    private static void ensureNotOnMainThread(@NonNull Context context) {
        Looper looper = Looper.myLooper();
        if (looper != null && looper == context.getMainLooper()) {
            throw new IllegalStateException(
                    "calling this from your main thread can lead to deadlock");
        }
    }
}
