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

Commit 48c47b91 authored by Dmitry Dementyev's avatar Dmitry Dementyev Committed by Android (Google) Code Review
Browse files

Merge "Add flag to guard remote lock screen verification API."

parents c8a66d05 2b769285
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -166,6 +166,13 @@ public class FeatureFlagUtils {
    public static final String SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS =
            "settings_show_udfps_enroll_in_settings";

    /**
     * Flag to enable lock screen credentials transfer API in Android U.
     * @hide
     */
    public static final String SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API =
            "settings_enable_lockscreen_transfer_api";

    private static final Map<String, String> DEFAULT_FLAGS;

    static {
@@ -207,6 +214,7 @@ public class FeatureFlagUtils {
        DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false");
        DEFAULT_FLAGS.put(SETTINGS_FLASH_ALERTS, "false");
        DEFAULT_FLAGS.put(SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, "false");
        DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "false");
    }

    private static final Set<String> PERSISTENT_FLAGS;
+23 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.FeatureFlagUtils;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseArray;
@@ -2503,6 +2504,28 @@ public class LockSettingsService extends ILockSettings.Stub {
        return mRecoverableKeyStoreManager.getKey(alias);
    }

    /**
     * Starts a session to verify lock screen credentials provided by a remote device.
     */
    public void startRemoteLockscreenValidation() {
        if (!FeatureFlagUtils.isEnabled(mContext,
                FeatureFlagUtils.SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API)) {
            throw new UnsupportedOperationException("Under development");
        }
        mRecoverableKeyStoreManager.startRemoteLockscreenValidation();
    }

    /**
     * Verifies credentials guess from a remote device.
     */
    public void validateRemoteLockscreen(@NonNull byte[] encryptedCredential) {
        if (!FeatureFlagUtils.isEnabled(mContext,
                FeatureFlagUtils.SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API)) {
            throw new UnsupportedOperationException("Under development");
        }
        mRecoverableKeyStoreManager.validateRemoteLockscreen(encryptedCredential);
    }

    // Reading these settings needs the contacts permission
    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
+29 −0
Original line number Diff line number Diff line
@@ -965,6 +965,35 @@ public class RecoverableKeyStoreManager {
        }
    }

    /**
     * Starts a session to verify lock screen credentials provided by a remote device.
     */
    public void startRemoteLockscreenValidation() {
        checkVerifyRemoteLockscreenPermission();
        // TODO(b/254335492): Create session in memory
        return;
    }

    /**
     * Verifies encrypted credentials guess from a remote device.
     */
    public void validateRemoteLockscreen(@NonNull byte[] encryptedCredential) {
        checkVerifyRemoteLockscreenPermission();
        // TODO(b/254335492): Decrypt and verify credentials
        return;
    }

    private void checkVerifyRemoteLockscreenPermission() {
        // TODO(b/254335492): Check new system permission
        mContext.enforceCallingOrSelfPermission(
                Manifest.permission.RECOVER_KEYSTORE,
                "Caller " + Binder.getCallingUid()
                        + " doesn't have verifyRemoteLockscreen permission.");
        int userId = UserHandle.getCallingUserId();
        int uid = Binder.getCallingUid();
        mCleanupManager.registerRecoveryAgent(userId, uid);
    }

    private void checkRecoverKeyStorePermission() {
        mContext.enforceCallingOrSelfPermission(
                Manifest.permission.RECOVER_KEYSTORE,
+89 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.Nullable;
import android.util.SparseArray;

import java.security.KeyPair;

/**
 * Memory based storage for keyPair used to send encrypted credentials from a remote device.
 *
 * @hide
 */
public class RemoteLockscreenValidationSessionStorage {

    private final SparseArray<LockScreenVerificationSession> mSessionsByUserId =
            new SparseArray<>();

    /**
     * Returns session for given user or null.
     *
     * @param userId The user id
     * @return The session info.
     *
     * @hide
     */
    @Nullable
    public LockScreenVerificationSession get(int userId) {
        return mSessionsByUserId.get(userId);
    }

    /**
     * Creates a new session to verify lockscreen credentials guess.
     *
     * Session will be automatically removed after 10 minutes of inactivity.
     * @param userId The user id
     *
     * @hide
     */
    public LockScreenVerificationSession startSession(int userId) {
        if (mSessionsByUserId.get(userId) != null) {
            mSessionsByUserId.remove(userId);
        }
        LockScreenVerificationSession newSession = null;
        // TODO(b/254335492): Schedule a task to remove session.
        mSessionsByUserId.put(userId, newSession);
        return newSession;
    }

    /**
     * Deletes session for a user.
     */
    public void remove(int userId) {
        mSessionsByUserId.remove(userId);
    }

    /**
     * Holder for keypair used by remote lock screen validation.
     *
     * @hide
     */
    public static class LockScreenVerificationSession {
        private final KeyPair mKeyPair;
        private final long mSessionStartTimeMillis;

        /**
         * @hide
         */
        public LockScreenVerificationSession(KeyPair keyPair, long sessionStartTimeMillis) {
            mKeyPair = keyPair;
            mSessionStartTimeMillis = sessionStartTimeMillis;
        }
    }
}