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

Commit 8d1ff46d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Don't create recovery snapshot until it contains at least one key." into pi-dev

parents 4af3d1a4 925f026c
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -232,9 +232,6 @@ public class RecoverableKeyStoreManager {
            throw new ServiceSpecificException(ERROR_INVALID_CERTIFICATE, e.getMessage());
        }

        boolean wasInitialized = mDatabase.getRecoveryServiceCertPath(userId, uid,
                rootCertificateAlias) != null;

        // Save the chosen and validated certificate into database
        try {
            Log.d(TAG, "Saving the randomly chosen endpoint certificate to database");
@@ -242,9 +239,11 @@ public class RecoverableKeyStoreManager {
                    certPath) > 0) {
                mDatabase.setRecoveryServiceCertSerial(userId, uid, rootCertificateAlias,
                        newSerial);
                if (wasInitialized) {
                    Log.i(TAG, "This is a certificate change. Snapshot pending.");
                if (mDatabase.getSnapshotVersion(userId, uid) != null) {
                    mDatabase.setShouldCreateSnapshot(userId, uid, true);
                    Log.i(TAG, "This is a certificate change. Snapshot must be updated");
                } else {
                    Log.i(TAG, "This is a certificate change. Snapshot didn't exist");
                }
                mDatabase.setCounterId(userId, uid, new SecureRandom().nextLong());
            }
@@ -350,8 +349,12 @@ public class RecoverableKeyStoreManager {
            return;
        }

        Log.i(TAG, "Updated server params. Snapshot pending.");
        if (mDatabase.getSnapshotVersion(userId, uid) != null) {
            mDatabase.setShouldCreateSnapshot(userId, uid, true);
            Log.i(TAG, "Updated server params. Snapshot must be updated");
        } else {
            Log.i(TAG, "Updated server params. Snapshot didn't exist");
        }
    }

    /**
@@ -407,7 +410,12 @@ public class RecoverableKeyStoreManager {
        }

        Log.i(TAG, "Updated secret types. Snapshot pending.");
        if (mDatabase.getSnapshotVersion(userId, uid) != null) {
            mDatabase.setShouldCreateSnapshot(userId, uid, true);
            Log.i(TAG, "Updated secret types. Snapshot must be updated");
        } else {
            Log.i(TAG, "Updated secret types. Snapshot didn't exist");
        }
    }

    /**
+12 −3
Original line number Diff line number Diff line
@@ -789,11 +789,20 @@ public class RecoverableKeyStoreDb {
    }

    /**
     * Updates the snapshot version.
     * Updates a flag indicating that a new snapshot should be created.
     * It will be {@code false} until the first application key is added.
     * After that, the flag will be set to true, if one of the following values is updated:
     * <ul>
     *     <li> List of application keys
     *     <li> Server params.
     *     <li> Lock-screen secret.
     *     <li> Lock-screen secret type.
     *     <li> Trusted hardware certificate.
     * </ul>
     *
     * @param userId The userId of the profile the application is running under.
     * @param uid The uid of the application.
     * @param pending The server parameters.
     * @param pending Should create snapshot flag.
     * @return The primary key of the inserted row, or -1 if failed.
     *
     * @hide
@@ -809,7 +818,7 @@ public class RecoverableKeyStoreDb {
     *
     * @param userId The userId of the profile the application is running under.
     * @param uid The uid of the application who initialized the local recovery components.
     * @return snapshot outdated flag.
     * @return should create snapshot flag
     *
     * @hide
     */
+57 −7
Original line number Diff line number Diff line
@@ -301,6 +301,33 @@ public class RecoverableKeyStoreManagerTest {
        assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isNull();
    }

    @Test
    public void initRecoveryService_updatesShouldCreatesnapshotOnCertUpdate() throws Exception {
        int uid = Binder.getCallingUid();
        int userId = UserHandle.getCallingUserId();
        long certSerial = 1000L;
        mRecoverableKeyStoreDb.setShouldCreateSnapshot(userId, uid, false);

        mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
                TestData.getCertXmlWithSerial(certSerial));

        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();

        mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
                TestData.getCertXmlWithSerial(certSerial + 1));

        // Since there were no recoverable keys, new snapshot will not be created.
        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();

        generateKeyAndSimulateSync(userId, uid, 10);

        mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
                TestData.getCertXmlWithSerial(certSerial + 2));

        // Since there were a recoverable key, new serial number triggers snapshot creation
        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
    }

    @Test
    public void initRecoveryService_triesToFilterRootAlias() throws Exception {
        int uid = Binder.getCallingUid();
@@ -405,7 +432,8 @@ public class RecoverableKeyStoreManagerTest {

        assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid,
                DEFAULT_ROOT_CERT_ALIAS)).isEqualTo(certSerial + 1);
        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
        // There were no keys.
        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
    }

    @Test
@@ -479,10 +507,12 @@ public class RecoverableKeyStoreManagerTest {

        mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
                TestData.getCertXmlWithSerial(certSerial));

        generateKeyAndSimulateSync(userId, uid, 10);

        mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
                TestData.getCertXmlWithSerial(certSerial));

        // If the second update succeeds, getShouldCreateSnapshot() will return true.
        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
    }

@@ -935,7 +965,6 @@ public class RecoverableKeyStoreManagerTest {

        assertThat(recoveredKeys).hasSize(1);
        assertThat(recoveredKeys).containsKey(TEST_ALIAS);
        // TODO(76083050) Test the grant mechanism for the keys.
    }

    @Test
@@ -974,7 +1003,6 @@ public class RecoverableKeyStoreManagerTest {

        assertThat(recoveredKeys).hasSize(1);
        assertThat(recoveredKeys).containsKey(TEST_ALIAS2);
        // TODO(76083050) Test the grant mechanism for the keys.
    }

    @Test
@@ -1016,6 +1044,9 @@ public class RecoverableKeyStoreManagerTest {
        byte[] serverParams = new byte[] { 1 };

        mRecoverableKeyStoreManager.setServerParams(serverParams);

        generateKeyAndSimulateSync(userId, uid, 10);

        mRecoverableKeyStoreManager.setServerParams(serverParams);

        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
@@ -1027,6 +1058,9 @@ public class RecoverableKeyStoreManagerTest {
        int userId = UserHandle.getCallingUserId();

        mRecoverableKeyStoreManager.setServerParams(new byte[] { 1 });

        generateKeyAndSimulateSync(userId, uid, 10);

        mRecoverableKeyStoreManager.setServerParams(new byte[] { 2 });

        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
@@ -1059,6 +1093,7 @@ public class RecoverableKeyStoreManagerTest {

        mRecoverableKeyStoreManager.setRecoverySecretTypes(secretTypes);

        // There were no keys.
        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
    }

@@ -1070,6 +1105,9 @@ public class RecoverableKeyStoreManagerTest {
        int[] secretTypes = new int[] { 101 };

        mRecoverableKeyStoreManager.setRecoverySecretTypes(secretTypes);

        generateKeyAndSimulateSync(userId, uid, 10);

        mRecoverableKeyStoreManager.setRecoverySecretTypes(secretTypes);

        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
@@ -1081,6 +1119,11 @@ public class RecoverableKeyStoreManagerTest {
        int userId = UserHandle.getCallingUserId();

        mRecoverableKeyStoreManager.setRecoverySecretTypes(new int[] { 101 });

        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();

        generateKeyAndSimulateSync(userId, uid, 10);

        mRecoverableKeyStoreManager.setRecoverySecretTypes(new int[] { 102 });

        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
@@ -1102,9 +1145,8 @@ public class RecoverableKeyStoreManagerTest {
        int userId = UserHandle.getCallingUserId();
        mRecoverableKeyStoreManager.setRecoverySecretTypes(new int[] { 1 });

        mRecoverableKeyStoreManager.generateKey(TEST_ALIAS);
        // Pretend that key was synced
        mRecoverableKeyStoreDb.setShouldCreateSnapshot(userId, uid, false);
        generateKeyAndSimulateSync(userId, uid, 10);

        mRecoverableKeyStoreManager.setRecoverySecretTypes(new int[] { 2 });

        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
@@ -1175,6 +1217,14 @@ public class RecoverableKeyStoreManagerTest {
        return bytes;
    }

    private void generateKeyAndSimulateSync(int userId, int uid, int snapshotVersion)
            throws Exception{
        mRecoverableKeyStoreManager.generateKey(TEST_ALIAS);
        // Simulate key sync.
        mRecoverableKeyStoreDb.setSnapshotVersion(userId, uid, snapshotVersion);
        mRecoverableKeyStoreDb.setShouldCreateSnapshot(userId, uid, false);
    }

    private AndroidKeyStoreSecretKey generateAndroidKeyStoreKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(
                KEY_ALGORITHM,