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

Commit dbf8a7c1 authored by Dmitry Dementyev's avatar Dmitry Dementyev Committed by Gerrit Code Review
Browse files

Merge "Migrate recoverablekeystore to KeyStore V2."

parents 594e8def 16491e13
Loading
Loading
Loading
Loading
+32 −5
Original line number Diff line number Diff line
@@ -27,8 +27,11 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.security.KeyStore;
import android.security.keystore.AndroidKeyStoreProvider;
import android.security.KeyStore2;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore2.AndroidKeyStoreProvider;
import android.system.keystore2.Domain;
import android.system.keystore2.KeyDescriptor;

import com.android.internal.widget.ILockSettings;

@@ -709,10 +712,34 @@ public class RecoveryController {
     */
    @NonNull Key getKeyFromGrant(@NonNull String grantAlias)
            throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
        return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
        if (grantAlias.startsWith(APPLICATION_KEY_GRANT_PREFIX)) {
            return AndroidKeyStoreProvider
                    .loadAndroidKeyStoreSecretKeyFromKeystore(
                            KeyStore2.getInstance(),
                            getGrantDescriptor(grantAlias));
        }
        // TODO(b/171305545): remove KeyStore1 logic.
        return android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
            mKeyStore,
            grantAlias,
            KeyStore.UID_SELF);

    }

    private static final String APPLICATION_KEY_GRANT_PREFIX = "recoverable_key:";

    private static @Nullable KeyDescriptor getGrantDescriptor(String grantAlias) {
        KeyDescriptor result = new KeyDescriptor();
        result.domain = Domain.GRANT;
        result.blob = null;
        result.alias = null;
        try {
            result.nspace = Long.parseUnsignedLong(
                    grantAlias.substring(APPLICATION_KEY_GRANT_PREFIX.length()), 16);
        } catch (NumberFormatException e) {
            return null;
        }
        return result;
    }

    /**
+15 −2
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import java.security.interfaces.RSAPublicKey;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.SecretKey;

/**
 * A provider focused on providing JCA interfaces for the Android KeyStore.
@@ -299,13 +300,26 @@ public class AndroidKeyStoreProvider extends Provider {
        }
    }

    /** @hide **/
    @NonNull
    public static SecretKey loadAndroidKeyStoreSecretKeyFromKeystore(
            @NonNull KeyStore2 keyStore, @NonNull KeyDescriptor descriptor)
            throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {

        AndroidKeyStoreKey key =
                loadAndroidKeyStoreKeyFromKeystore(keyStore, descriptor);
        if (key instanceof SecretKey) {
            return (SecretKey) key;
        } else {
            throw new UnrecoverableKeyException("No secret key found by the given alias.");
        }
    }

    @NonNull
    private static AndroidKeyStoreSecretKey makeAndroidKeyStoreSecretKeyFromKeyEntryResponse(
            @NonNull KeyDescriptor descriptor,
            @NonNull KeyEntryResponse response, int algorithm, int digest)
            throws UnrecoverableKeyException {

        @KeyProperties.KeyAlgorithmEnum String keyAlgorithmString;
        try {
            keyAlgorithmString = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(
@@ -337,7 +351,6 @@ public class AndroidKeyStoreProvider extends Provider {
    public static AndroidKeyStoreKey loadAndroidKeyStoreKeyFromKeystore(
            @NonNull KeyStore2 keyStore, @NonNull String alias, int namespace)
            throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {

        KeyDescriptor descriptor = new KeyDescriptor();
        if (namespace == KeyProperties.NAMESPACE_APPLICATION) {
            descriptor.nspace = KeyProperties.NAMESPACE_APPLICATION; // ignored;
+3 −3
Original line number Diff line number Diff line
@@ -489,8 +489,8 @@ public class LockSettingsService extends ILockSettings.Stub {
            return KeyStore.getInstance();
        }

        public RecoverableKeyStoreManager getRecoverableKeyStoreManager(KeyStore keyStore) {
            return RecoverableKeyStoreManager.getInstance(mContext, keyStore);
        public RecoverableKeyStoreManager getRecoverableKeyStoreManager() {
            return RecoverableKeyStoreManager.getInstance(mContext);
        }

        public IStorageManager getStorageManager() {
@@ -571,7 +571,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        mInjector = injector;
        mContext = injector.getContext();
        mKeyStore = injector.getKeyStore();
        mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(mKeyStore);
        mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager();
        mHandler = injector.getHandler(injector.getServiceThread());
        mStrongAuth = injector.getStrongAuth();
        mActivityManager = injector.getActivityManager();
+3 −18
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.server.locksettings.recoverablekeystore;

import android.security.keystore2.AndroidKeyStoreProvider;

import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
@@ -31,22 +29,9 @@ import java.security.cert.CertificateException;
 */
public class KeyStoreProxyImpl implements KeyStoreProxy {

    private final KeyStore mKeyStore;

    /**
     * TODO This function redirects keystore access to the legacy keystore during a transitional
     *      phase during which not all calling code has been adjusted to use Keystore 2.0.
     *      This can be reverted to a constant of "AndroidKeyStore" when b/171305684 is complete.
     *      The specific bug for this component is b/171305545.
     */
    static String androidKeystoreProviderName() {
        if (AndroidKeyStoreProvider.isInstalled()) {
            return "AndroidKeyStoreLegacy";
        } else {
            return "AndroidKeyStore";
        }
    public static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore";

    }
    private final KeyStore mKeyStore;

    /**
     * A new instance, delegating to {@code keyStore}.
@@ -84,7 +69,7 @@ public class KeyStoreProxyImpl implements KeyStoreProxy {
     * @throws KeyStoreException if there was a problem getting or initializing the key store.
     */
    public static KeyStore getAndLoadAndroidKeyStore() throws KeyStoreException {
        KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
        KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER);
        try {
            keyStore.load(/*param=*/ null);
        } catch (CertificateException | IOException | NoSuchAlgorithmException e) {
+1 −1
Original line number Diff line number Diff line
@@ -484,7 +484,7 @@ public class PlatformKeyManager {
     * @throws KeyStoreException if there was a problem getting or initializing the key store.
     */
    private static KeyStore getAndLoadAndroidKeyStore() throws KeyStoreException {
        KeyStore keyStore = KeyStore.getInstance(KeyStoreProxyImpl.androidKeystoreProviderName());
        KeyStore keyStore = KeyStore.getInstance(KeyStoreProxyImpl.ANDROID_KEY_STORE_PROVIDER);
        try {
            keyStore.load(/*param=*/ null);
        } catch (CertificateException | IOException | NoSuchAlgorithmException e) {
Loading