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

Commit 64a94872 authored by Dmitry Dementyev's avatar Dmitry Dementyev Committed by android-build-merger
Browse files

Merge "Prepare KeyChainSnapshot to removing deprecated...

Merge "Prepare KeyChainSnapshot to removing deprecated getTrustedHardwarePublicKey method." into pi-dev
am: 95f2965a

Change-Id: I2e44ca18a1f3fa928f3a3529a1425a483dd34d06
parents a87c6da0 95f2965a
Loading
Loading
Loading
Loading
+13 −21
Original line number Diff line number Diff line
@@ -127,11 +127,7 @@ public final class KeyChainSnapshot implements Parcelable {
    /**
     * CertPath containing the public key used to encrypt {@code encryptedRecoveryKeyBlob}.
     */
    // TODO: Change to @NonNull
    public CertPath getTrustedHardwareCertPath() {
        if (mCertPath == null) {
            return null;
        } else {
    public @NonNull CertPath getTrustedHardwareCertPath() {
        try {
            return mCertPath.getCertPath();
        } catch (CertificateException e) {
@@ -140,7 +136,6 @@ public final class KeyChainSnapshot implements Parcelable {
            throw new BadParcelableException(e);
        }
    }
    }

    /**
     * UI and key derivation parameters. Note that combination of secrets may be used.
@@ -248,13 +243,9 @@ public final class KeyChainSnapshot implements Parcelable {
         * @throws CertificateException if the given certificate path cannot be encoded properly
         * @return This builder.
         */
        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 {
        public Builder setTrustedHardwareCertPath(@NonNull CertPath certPath)
                throws CertificateException {
            mInstance.mCertPath = RecoveryCertPath.createRecoveryCertPath(certPath);
            }
            return this;
        }

@@ -282,7 +273,7 @@ public final class KeyChainSnapshot implements Parcelable {
        }

        /**
         * Sets recovery key blob
         * Sets recovery key blob.
         *
         * @param encryptedRecoveryKeyBlob The recovery key blob.
         * @return This builder.
@@ -297,7 +288,7 @@ public final class KeyChainSnapshot implements Parcelable {
         * Creates a new {@link KeyChainSnapshot} instance.
         *
         * @return new instance
         * @throws NullPointerException if some required fields were not set.
         * @throws NullPointerException if some of the required fields were not set.
         */
        @NonNull public KeyChainSnapshot build() {
            Preconditions.checkCollectionElementsNotNull(mInstance.mKeyChainProtectionParams,
@@ -306,6 +297,7 @@ public final class KeyChainSnapshot implements Parcelable {
                    "entryRecoveryData");
            Preconditions.checkNotNull(mInstance.mEncryptedRecoveryKeyBlob);
            Preconditions.checkNotNull(mInstance.mServerParams);
            Preconditions.checkNotNull(mInstance.mCertPath);
            return mInstance;
        }
    }
+0 −298
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.locksettings.recoverablekeystore.storage;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.security.keystore.recovery.KeyChainProtectionParams;
import android.security.keystore.recovery.KeyChainSnapshot;
import android.security.keystore.recovery.KeyDerivationParams;
import android.security.keystore.recovery.WrappedApplicationKey;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * This class provides helper methods serialize and deserialize {@link KeyChainSnapshot}.
 *
 * <p> It is necessary since {@link android.os.Parcelable} is not designed for persistent storage.
 *
 * <p> For every list, length is stored before the elements.
 *
 */
public class PersistentKeyChainSnapshot {
    private static final int VERSION = 1;
    private static final int NULL_LIST_LENGTH = -1;

    private DataInputStream mInput;
    private DataOutputStream mOut;
    private ByteArrayOutputStream mOutStream;

    @VisibleForTesting
    PersistentKeyChainSnapshot() {
    }

    @VisibleForTesting
    void initReader(byte[] input) {
        mInput = new DataInputStream(new ByteArrayInputStream(input));
    }

    @VisibleForTesting
    void initWriter() {
        mOutStream = new ByteArrayOutputStream();
        mOut = new DataOutputStream(mOutStream);
    }

    @VisibleForTesting
    byte[] getOutput() {
        return mOutStream.toByteArray();
    }

    /**
     * Converts {@link KeyChainSnapshot} to its binary representation.
     *
     * @param snapshot The snapshot.
     *
     * @throws IOException if serialization failed.
     */
    public static byte[] serialize(@NonNull KeyChainSnapshot snapshot) throws IOException {
        PersistentKeyChainSnapshot writer = new PersistentKeyChainSnapshot();
        writer.initWriter();
        writer.writeInt(VERSION);
        writer.writeKeyChainSnapshot(snapshot);
        return writer.getOutput();
    }

    /**
     * deserializes {@link KeyChainSnapshot}.
     *
     * @input input - byte array produced by {@link serialize} method.
     * @throws IOException if parsing failed.
     */
    public static @NonNull KeyChainSnapshot deserialize(@NonNull byte[] input)
            throws IOException {
        PersistentKeyChainSnapshot reader = new PersistentKeyChainSnapshot();
        reader.initReader(input);
        try {
            int version = reader.readInt();
            if (version != VERSION) {
                throw new IOException("Unsupported version " + version);
            }
            return reader.readKeyChainSnapshot();
        } catch (IOException e) {
            throw new IOException("Malformed KeyChainSnapshot", e);
        }
    }

    /**
     * Must be in sync with {@link KeyChainSnapshot.writeToParcel}
     */
    @VisibleForTesting
    void writeKeyChainSnapshot(KeyChainSnapshot snapshot) throws IOException {
        writeInt(snapshot.getSnapshotVersion());
        writeProtectionParamsList(snapshot.getKeyChainProtectionParams());
        writeBytes(snapshot.getEncryptedRecoveryKeyBlob());
        writeKeysList(snapshot.getWrappedApplicationKeys());

        writeInt(snapshot.getMaxAttempts());
        writeLong(snapshot.getCounterId());
        writeBytes(snapshot.getServerParams());
        writeBytes(snapshot.getTrustedHardwarePublicKey());
    }

    @VisibleForTesting
    KeyChainSnapshot readKeyChainSnapshot() throws IOException {
        int snapshotVersion = readInt();
        List<KeyChainProtectionParams> protectionParams = readProtectionParamsList();
        byte[] encryptedRecoveryKey = readBytes();
        List<WrappedApplicationKey> keysList = readKeysList();

        int maxAttempts = readInt();
        long conterId = readLong();
        byte[] serverParams = readBytes();
        byte[] trustedHardwarePublicKey = readBytes();

        return new KeyChainSnapshot.Builder()
                .setSnapshotVersion(snapshotVersion)
                .setKeyChainProtectionParams(protectionParams)
                .setEncryptedRecoveryKeyBlob(encryptedRecoveryKey)
                .setWrappedApplicationKeys(keysList)
                .setMaxAttempts(maxAttempts)
                .setCounterId(conterId)
                .setServerParams(serverParams)
                .setTrustedHardwarePublicKey(trustedHardwarePublicKey)
                .build();
    }

    @VisibleForTesting
    void writeProtectionParamsList(
            @NonNull List<KeyChainProtectionParams> ProtectionParamsList) throws IOException {
        writeInt(ProtectionParamsList.size());
        for (KeyChainProtectionParams protectionParams : ProtectionParamsList) {
            writeProtectionParams(protectionParams);
        }
    }

    @VisibleForTesting
    List<KeyChainProtectionParams> readProtectionParamsList() throws IOException {
        int length = readInt();
        List<KeyChainProtectionParams> result = new ArrayList<>(length);
        for (int i = 0; i < length; i++) {
            result.add(readProtectionParams());
        }
        return result;
    }

    /**
     * Must be in sync with {@link KeyChainProtectionParams.writeToParcel}
     */
    @VisibleForTesting
    void writeProtectionParams(@NonNull KeyChainProtectionParams protectionParams)
            throws IOException {
        if (!ArrayUtils.isEmpty(protectionParams.getSecret())) {
            // Extra security check.
            throw new RuntimeException("User generated secret should not be stored");
        }
        writeInt(protectionParams.getUserSecretType());
        writeInt(protectionParams.getLockScreenUiFormat());
        writeKeyDerivationParams(protectionParams.getKeyDerivationParams());
        writeBytes(protectionParams.getSecret());
    }

    @VisibleForTesting
    KeyChainProtectionParams readProtectionParams() throws IOException {
        int userSecretType = readInt();
        int lockScreenUiFormat = readInt();
        KeyDerivationParams derivationParams = readKeyDerivationParams();
        byte[] secret = readBytes();
        return new KeyChainProtectionParams.Builder()
                .setUserSecretType(userSecretType)
                .setLockScreenUiFormat(lockScreenUiFormat)
                .setKeyDerivationParams(derivationParams)
                .setSecret(secret)
                .build();
    }

    /**
     * Must be in sync with {@link KeyDerivationParams.writeToParcel}
     */
    @VisibleForTesting
    void writeKeyDerivationParams(@NonNull KeyDerivationParams Params) throws IOException {
        writeInt(Params.getAlgorithm());
        writeBytes(Params.getSalt());
    }

    @VisibleForTesting
    KeyDerivationParams readKeyDerivationParams() throws IOException {
        int algorithm = readInt();
        byte[] salt = readBytes();
        return KeyDerivationParams.createSha256Params(salt);
    }

    @VisibleForTesting
    void writeKeysList(@NonNull List<WrappedApplicationKey> applicationKeys) throws IOException {
        writeInt(applicationKeys.size());
        for (WrappedApplicationKey keyEntry : applicationKeys) {
            writeKeyEntry(keyEntry);
        }
    }

    @VisibleForTesting
    List<WrappedApplicationKey> readKeysList() throws IOException {
        int length = readInt();
        List<WrappedApplicationKey> result = new ArrayList<>(length);
        for (int i = 0; i < length; i++) {
            result.add(readKeyEntry());
        }
        return result;
    }

    /**
     * Must be in sync with {@link WrappedApplicationKey.writeToParcel}
     */
    @VisibleForTesting
    void writeKeyEntry(@NonNull WrappedApplicationKey keyEntry) throws IOException {
        mOut.writeUTF(keyEntry.getAlias());
        writeBytes(keyEntry.getEncryptedKeyMaterial());
        writeBytes(keyEntry.getAccount());
    }

    @VisibleForTesting
    WrappedApplicationKey readKeyEntry() throws IOException {
        String alias = mInput.readUTF();
        byte[] keyMaterial = readBytes();
        byte[] account = readBytes();
        return new WrappedApplicationKey.Builder()
                .setAlias(alias)
                .setEncryptedKeyMaterial(keyMaterial)
                .setAccount(account)
                .build();
    }

    @VisibleForTesting
    void writeInt(int value) throws IOException {
        mOut.writeInt(value);
    }

    @VisibleForTesting
    int readInt() throws IOException {
        return mInput.readInt();
    }

    @VisibleForTesting
    void writeLong(long value) throws IOException {
        mOut.writeLong(value);
    }

    @VisibleForTesting
    long readLong() throws IOException {
        return mInput.readLong();
    }

    @VisibleForTesting
    void writeBytes(@Nullable byte[] value) throws IOException {
        if (value == null) {
            writeInt(NULL_LIST_LENGTH);
            return;
        }
        writeInt(value.length);
        mOut.write(value, 0, value.length);
    }

    /**
     * Reads @code{byte[]} from current position. Converts {@code null} to an empty array.
     */
    @VisibleForTesting
    @NonNull byte[] readBytes() throws IOException {
        int length = readInt();
        if (length == NULL_LIST_LENGTH) {
            return new byte[]{};
        }
        byte[] result = new byte[length];
        mInput.read(result, 0, result.length);
        return result;
    }
}
+34 −38
Original line number Diff line number Diff line
@@ -62,7 +62,6 @@ import org.mockito.MockitoAnnotations;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
@@ -95,7 +94,6 @@ public class KeySyncTaskTest {
    private RecoverySnapshotStorage mRecoverySnapshotStorage;
    private RecoverableKeyStoreDb mRecoverableKeyStoreDb;
    private File mDatabaseFile;
    private KeyPair mKeyPair;
    private AndroidKeyStoreSecretKey mWrappingKey;
    private PlatformEncryptionKey mEncryptKey;

@@ -108,7 +106,6 @@ public class KeySyncTaskTest {
        Context context = InstrumentationRegistry.getTargetContext();
        mDatabaseFile = context.getDatabasePath(DATABASE_FILE_NAME);
        mRecoverableKeyStoreDb = RecoverableKeyStoreDb.newInstance(context);
        mKeyPair = SecureBox.genKeyPair();

        mRecoverableKeyStoreDb.setRecoverySecretTypes(TEST_USER_ID, TEST_RECOVERY_AGENT_UID,
                new int[] {TYPE_LOCKSCREEN});
@@ -249,8 +246,8 @@ public class KeySyncTaskTest {
                TEST_RECOVERY_AGENT_UID,
                TEST_APP_KEY_ALIAS,
                WrappedKey.fromSecretKey(mEncryptKey, applicationKey));
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);

        mKeySyncTask.run();
@@ -265,8 +262,8 @@ public class KeySyncTaskTest {
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_VAULT_HANDLE);
        mRecoverableKeyStoreDb.setPlatformKeyGenerationId(TEST_USER_ID, TEST_GENERATION_ID);
        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);

        mKeySyncTask.run();

@@ -275,8 +272,8 @@ public class KeySyncTaskTest {

    @Test
    public void run_sendsEncryptedKeysIfAvailableToSync_withRawPublicKey() throws Exception {
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);

        mRecoverableKeyStoreDb.setServerParams(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_VAULT_HANDLE);
@@ -301,7 +298,7 @@ public class KeySyncTaskTest {
                lockScreenHash,
                keyChainSnapshot.getEncryptedRecoveryKeyBlob(),
                /*vaultParams=*/ KeySyncUtils.packVaultParams(
                        mKeyPair.getPublic(),
                        TestData.CERT_1_PUBLIC_KEY,
                        counterId,
                        /*maxAttempts=*/ 10,
                        TEST_VAULT_HANDLE));
@@ -309,8 +306,8 @@ public class KeySyncTaskTest {
        assertThat(applicationKeys).hasSize(1);
        assertThat(keyChainSnapshot.getCounterId()).isEqualTo(counterId);
        assertThat(keyChainSnapshot.getMaxAttempts()).isEqualTo(10);
        assertThat(keyChainSnapshot.getTrustedHardwarePublicKey())
                .isEqualTo(SecureBox.encodePublicKey(mKeyPair.getPublic()));
        assertThat(keyChainSnapshot.getTrustedHardwareCertPath())
                .isEqualTo(TestData.CERT_PATH_1);
        assertThat(keyChainSnapshot.getServerParams()).isEqualTo(TEST_VAULT_HANDLE);
        WrappedApplicationKey keyData = applicationKeys.get(0);
        assertEquals(TEST_APP_KEY_ALIAS, keyData.getAlias());
@@ -335,15 +332,14 @@ public class KeySyncTaskTest {
        verify(mSnapshotListenersStorage).recoverySnapshotAvailable(TEST_RECOVERY_AGENT_UID);
        List<WrappedApplicationKey> applicationKeys = keyChainSnapshot.getWrappedApplicationKeys();
        assertThat(applicationKeys).hasSize(1);
        assertThat(keyChainSnapshot.getTrustedHardwarePublicKey())
                .isEqualTo(SecureBox.encodePublicKey(
                        TestData.CERT_PATH_1.getCertificates().get(0).getPublicKey()));
        assertThat(keyChainSnapshot.getTrustedHardwareCertPath())
                .isEqualTo(TestData.CERT_PATH_1);
    }

    @Test
    public void run_setsCorrectSnapshotVersion() throws Exception {
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);

@@ -361,8 +357,8 @@ public class KeySyncTaskTest {

    @Test
    public void run_recreatesMissingSnapshot() throws Exception {
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);

@@ -391,8 +387,8 @@ public class KeySyncTaskTest {
                /*credentialUpdated=*/ false,
                mPlatformKeyManager);

        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
        SecretKey applicationKey =
                addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
@@ -417,8 +413,8 @@ public class KeySyncTaskTest {
                /*credentialUpdated=*/ false,
                mPlatformKeyManager);

        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
        SecretKey applicationKey =
                addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
@@ -444,8 +440,8 @@ public class KeySyncTaskTest {
                /*credentialUpdated=*/ false,
                mPlatformKeyManager);

        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
        SecretKey applicationKey =
                addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
@@ -460,10 +456,10 @@ public class KeySyncTaskTest {

    @Test
    public void run_sendsEncryptedKeysWithTwoRegisteredAgents() throws Exception {
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID2, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID2, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID2)).thenReturn(true);
        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
@@ -482,10 +478,10 @@ public class KeySyncTaskTest {
        mRecoverableKeyStoreDb.setRecoverySecretTypes(TEST_USER_ID, TEST_RECOVERY_AGENT_UID2,
                new int[] {1000});

        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID2, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID2, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID2)).thenReturn(true);
        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
@@ -499,10 +495,10 @@ public class KeySyncTaskTest {

    @Test
    public void run_notifiesNonregisteredAgent() throws Exception {
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServicePublicKey(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID2, mKeyPair.getPublic());
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TestData.CERT_PATH_1);
        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                TEST_USER_ID, TEST_RECOVERY_AGENT_UID2, TestData.CERT_PATH_1);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
        when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID2)).thenReturn(false);
        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
@@ -562,7 +558,7 @@ public class KeySyncTaskTest {
    private byte[] decryptThmEncryptedKey(
            byte[] lockScreenHash, byte[] encryptedKey, byte[] vaultParams) throws Exception {
        byte[] locallyEncryptedKey = SecureBox.decrypt(
                mKeyPair.getPrivate(),
                TestData.CERT_1_PRIVATE_KEY,
                /*sharedSecret=*/ KeySyncUtils.calculateThmKfHash(lockScreenHash),
                /*header=*/ KeySyncUtils.concat(THM_ENCRYPTED_RECOVERY_KEY_HEADER, vaultParams),
                encryptedKey
+53 −1

File changed.

Preview size limit exceeded, changes collapsed.

+0 −331

File deleted.

Preview size limit exceeded, changes collapsed.