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

Commit 16491e13 authored by Dmitry Dementyev's avatar Dmitry Dementyev
Browse files

Migrate recoverablekeystore to KeyStore V2.

Test: manual
Bug: 171305545
Change-Id: Id415be48cab6852df155b5b2dbaf941ef54cd5a4
parent eb45aabc
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