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

Commit 63610807 authored by Bo Zhu's avatar Bo Zhu
Browse files

DO NOT MERGE Fix the null return value of getTrustedHardwareCertPath

I forgot to serialize and deserialize it in the last CL adding it.

Bug: 74359698
Change-Id: I34f9225dc63b55223c2a7db23ee3fa6abf056a0d
Test: atest RecoveryControllerHostTest
(cherry picked from commit b4d2cc68)
parent 41b5ece1
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -18,12 +18,14 @@ package android.security.keystore.recovery;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.BadParcelableException;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.Preconditions;

import java.security.cert.CertPath;
import java.security.cert.CertificateException;
import java.util.List;

/**
@@ -54,7 +56,7 @@ public final class KeyChainSnapshot implements Parcelable {
    private long mCounterId = DEFAULT_COUNTER_ID;
    private byte[] mServerParams;
    private byte[] mPublicKey;  // The raw public key bytes used
    private CertPath mCertPath;  // The certificate path including the intermediate certificates
    private RecoveryCertPath mCertPath;  // The cert path including necessary intermediate certs
    private List<KeyChainProtectionParams> mKeyChainProtectionParams;
    private List<WrappedApplicationKey> mEntryRecoveryData;
    private byte[] mEncryptedRecoveryKeyBlob;
@@ -127,7 +129,17 @@ public final class KeyChainSnapshot implements Parcelable {
     */
    // TODO: Change to @NonNull
    public CertPath getTrustedHardwareCertPath() {
        return mCertPath;
        if (mCertPath == null) {
            return null;
        } else {
            try {
                return mCertPath.getCertPath();
            } catch (CertificateException e) {
                // Rethrow an unchecked exception as it should not happen. If such an issue exists,
                // an exception should have been thrown during service initialization.
                throw new BadParcelableException(e);
            }
        }
    }

    /**
@@ -232,11 +244,17 @@ public final class KeyChainSnapshot implements Parcelable {
         * contain a certificate of the trusted hardware public key and any necessary intermediate
         * certificates.
         *
         * @param certPath The public key
         * @param certPath The certificate path
         * @throws CertificateException if the given certificate path cannot be encoded properly
         * @return This builder.
         */
        public Builder setTrustedHardwareCertPath(CertPath certPath) {
            mInstance.mCertPath = certPath;
        public Builder setTrustedHardwareCertPath(CertPath certPath) throws CertificateException {
            // TODO: Make it NonNull when the caller code is all updated
            if (certPath == null) {
                mInstance.mCertPath = null;
            } else {
                mInstance.mCertPath = RecoveryCertPath.createRecoveryCertPath(certPath);
            }
            return this;
        }

@@ -302,6 +320,7 @@ public final class KeyChainSnapshot implements Parcelable {
        out.writeLong(mCounterId);
        out.writeByteArray(mServerParams);
        out.writeByteArray(mPublicKey);
        out.writeTypedObject(mCertPath, /* no flags */ 0);
    }

    /**
@@ -316,6 +335,7 @@ public final class KeyChainSnapshot implements Parcelable {
        mCounterId = in.readLong();
        mServerParams = in.createByteArray();
        mPublicKey = in.createByteArray();
        mCertPath = in.readTypedObject(RecoveryCertPath.CREATOR);
    }

    @Override
+11 −4
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertPath;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -295,17 +296,23 @@ public class KeySyncTask implements Runnable {
        // If application keys are not updated, snapshot will not be created on next unlock.
        mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, false);

        mRecoverySnapshotStorage.put(recoveryAgentUid, new KeyChainSnapshot.Builder()
        KeyChainSnapshot.Builder keyChainSnapshotBuilder = new KeyChainSnapshot.Builder()
                .setSnapshotVersion(getSnapshotVersion(recoveryAgentUid, recreateCurrentVersion))
                .setMaxAttempts(TRUSTED_HARDWARE_MAX_ATTEMPTS)
                .setCounterId(counterId)
                .setTrustedHardwarePublicKey(SecureBox.encodePublicKey(publicKey))
                .setTrustedHardwareCertPath(certPath)
                .setServerParams(vaultHandle)
                .setKeyChainProtectionParams(metadataList)
                .setWrappedApplicationKeys(createApplicationKeyEntries(encryptedApplicationKeys))
                .setEncryptedRecoveryKeyBlob(encryptedRecoveryKey)
                .build());
                .setEncryptedRecoveryKeyBlob(encryptedRecoveryKey);
        try {
            keyChainSnapshotBuilder.setTrustedHardwareCertPath(certPath);
        } catch(CertificateException e) {
            // Should not happen, as it's just deserialized from bytes stored in the db
            Log.wtf(TAG, "Cannot serialize CertPath when calling setTrustedHardwareCertPath", e);
            return;
        }
        mRecoverySnapshotStorage.put(recoveryAgentUid, keyChainSnapshotBuilder.build());

        mSnapshotListenersStorage.recoverySnapshotAvailable(recoveryAgentUid);
    }