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

Commit 23174b7e authored by Aseem Kumar's avatar Aseem Kumar
Browse files

Throw ServiceSpecificException if calling app tries to initialize

certificates with lower version. Earlier, the code just returned
silently, giving no indication that updating certs failed.

Change-Id: I3eb1b9f423791a655b47b3e76c20a170e2b632c0
Bug: 77533356
Test: runtest frameworks-services -p
    com.android.server.locksettings.recoverablekeystore
parent 6ae58e0d
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -250,6 +250,16 @@ public class RecoveryController {
     */
    public static final int ERROR_INVALID_CERTIFICATE = 28;


    /**
     * Failed because the provided certificate contained serial version which is lower that the
     * version device is already initialized with. It is not possible to downgrade serial version of
     * the provided certificate.
     *
     * @hide
     */
    public static final int ERROR_DOWNGRADE_CERTIFICATE = 29;

    private final ILockSettings mBinder;
    private final KeyStore mKeyStore;

@@ -340,6 +350,10 @@ public class RecoveryController {
                    || e.errorCode == ERROR_INVALID_CERTIFICATE) {
                throw new CertificateException("Invalid certificate for recovery service", e);
            }
            if (e.errorCode == ERROR_DOWNGRADE_CERTIFICATE) {
                throw new CertificateException(
                        "Downgrading certificate serial version isn't supported.", e);
            }
            throw wrapUnexpectedServiceSpecificException(e);
        }
    }
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.locksettings.recoverablekeystore;

import static android.security.keystore.recovery.RecoveryController.ERROR_BAD_CERTIFICATE_FORMAT;
import static android.security.keystore.recovery.RecoveryController.ERROR_DECRYPTION_FAILED;
import static android.security.keystore.recovery.RecoveryController.ERROR_DOWNGRADE_CERTIFICATE;
import static android.security.keystore.recovery.RecoveryController.ERROR_INSECURE_USER;
import static android.security.keystore.recovery.RecoveryController.ERROR_INVALID_KEY_FORMAT;
import static android.security.keystore.recovery.RecoveryController.ERROR_INVALID_CERTIFICATE;
@@ -212,6 +213,8 @@ public class RecoverableKeyStoreManager {
                Log.i(TAG, "The cert file serial number is the same, so skip updating.");
            } else {
                Log.e(TAG, "The cert file serial number is older than the one in database.");
                throw new ServiceSpecificException(ERROR_DOWNGRADE_CERTIFICATE,
                        "The cert file serial number is older than the one in database.");
            }
            return;
        }
+9 −7
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.locksettings.recoverablekeystore;
import static android.security.keystore.recovery.KeyChainProtectionParams.TYPE_LOCKSCREEN;
import static android.security.keystore.recovery.KeyChainProtectionParams.UI_FORMAT_PASSWORD;
import static android.security.keystore.recovery.RecoveryController.ERROR_BAD_CERTIFICATE_FORMAT;
import static android.security.keystore.recovery.RecoveryController.ERROR_DOWNGRADE_CERTIFICATE;
import static android.security.keystore.recovery.RecoveryController.ERROR_INVALID_CERTIFICATE;

import static com.google.common.truth.Truth.assertThat;
@@ -409,19 +410,20 @@ public class RecoverableKeyStoreManagerTest {
    }

    @Test
    public void initRecoveryService_ignoresSmallerSerial() throws Exception {
    public void initRecoveryService_throwsExceptionOnSmallerSerial() throws Exception {
        int uid = Binder.getCallingUid();
        int userId = UserHandle.getCallingUserId();
        long certSerial = 1000L;

        mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
                TestData.getCertXmlWithSerial(certSerial));
        try {
            mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
                    TestData.getCertXmlWithSerial(certSerial - 1));

        assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid,
                DEFAULT_ROOT_CERT_ALIAS)).isEqualTo(certSerial);
        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
            fail();
        } catch (ServiceSpecificException e) {
            assertThat(e.errorCode).isEqualTo(ERROR_DOWNGRADE_CERTIFICATE);
        }
    }

    @Test