Add remote lockscreen verification APIs to KeyguardManager.
Adds CHECK_REMOTE_LOCKSCREEN system permission. go/setup-lskf-apis Test: manual Bug: 254335492 Change-Id: Iab2f2ff5f710e05dfb2912201408bd12759695e2
This commit is contained in:
@@ -100,6 +100,7 @@ package android {
|
||||
field public static final String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
|
||||
field public static final String CHANGE_APP_LAUNCH_TIME_ESTIMATE = "android.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE";
|
||||
field public static final String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST";
|
||||
field public static final String CHECK_REMOTE_LOCKSCREEN = "android.permission.CHECK_REMOTE_LOCKSCREEN";
|
||||
field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
|
||||
field public static final String COMPANION_APPROVE_WIFI_CONNECTIONS = "android.permission.COMPANION_APPROVE_WIFI_CONNECTIONS";
|
||||
field public static final String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
|
||||
@@ -919,7 +920,9 @@ package android.app {
|
||||
method @RequiresPermission(android.Manifest.permission.SHOW_KEYGUARD_MESSAGE) public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable CharSequence, @Nullable android.app.KeyguardManager.KeyguardDismissCallback);
|
||||
method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public boolean setLock(int, @NonNull byte[], int);
|
||||
method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public void setPrivateNotificationsAllowed(boolean);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.app.StartLockscreenValidationRequest startRemoteLockscreenValidation();
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean unregisterWeakEscrowTokenRemovedListener(@NonNull android.app.KeyguardManager.WeakEscrowTokenRemovedListener);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.app.RemoteLockscreenValidationResult validateRemoteLockscreen(@NonNull byte[]);
|
||||
field public static final int PASSWORD = 0; // 0x0
|
||||
field public static final int PATTERN = 2; // 0x2
|
||||
field public static final int PIN = 1; // 0x1
|
||||
@@ -996,6 +999,25 @@ package android.app {
|
||||
field @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE) public static final String ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL = "android.app.action.TOGGLE_NOTIFICATION_HANDLER_PANEL";
|
||||
}
|
||||
|
||||
public final class RemoteLockscreenValidationResult implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getResultCode();
|
||||
method public long getTimeoutMillis();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.app.RemoteLockscreenValidationResult> CREATOR;
|
||||
field public static final int RESULT_GUESS_INVALID = 2; // 0x2
|
||||
field public static final int RESULT_GUESS_VALID = 1; // 0x1
|
||||
field public static final int RESULT_LOCKOUT = 3; // 0x3
|
||||
field public static final int RESULT_NO_REMAINING_ATTEMPTS = 4; // 0x4
|
||||
}
|
||||
|
||||
public static final class RemoteLockscreenValidationResult.Builder {
|
||||
ctor public RemoteLockscreenValidationResult.Builder();
|
||||
method @NonNull public android.app.RemoteLockscreenValidationResult build();
|
||||
method @NonNull public android.app.RemoteLockscreenValidationResult.Builder setResultCode(int);
|
||||
method @NonNull public android.app.RemoteLockscreenValidationResult.Builder setTimeoutMillis(long);
|
||||
}
|
||||
|
||||
public final class RuntimeAppOpAccessMessage implements android.os.Parcelable {
|
||||
ctor public RuntimeAppOpAccessMessage(@IntRange(from=0L) int, @IntRange(from=0L) int, @NonNull String, @Nullable String, @NonNull String, int);
|
||||
method public int describeContents();
|
||||
@@ -1013,6 +1035,23 @@ package android.app {
|
||||
method public void launchAssist(@Nullable android.os.Bundle);
|
||||
}
|
||||
|
||||
public final class StartLockscreenValidationRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getLockscreenUiType();
|
||||
method public int getRemainingAttempts();
|
||||
method @NonNull public byte[] getSourcePublicKey();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.app.StartLockscreenValidationRequest> CREATOR;
|
||||
}
|
||||
|
||||
public static final class StartLockscreenValidationRequest.Builder {
|
||||
ctor public StartLockscreenValidationRequest.Builder();
|
||||
method @NonNull public android.app.StartLockscreenValidationRequest build();
|
||||
method @NonNull public android.app.StartLockscreenValidationRequest.Builder setLockscreenUiType(int);
|
||||
method @NonNull public android.app.StartLockscreenValidationRequest.Builder setRemainingAttempts(int);
|
||||
method @NonNull public android.app.StartLockscreenValidationRequest.Builder setSourcePublicKey(@NonNull byte[]);
|
||||
}
|
||||
|
||||
public class StatusBarManager {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.STATUS_BAR) public android.app.StatusBarManager.DisableInfo getDisableInfo();
|
||||
method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public int getNavBarMode();
|
||||
|
||||
@@ -1075,6 +1075,46 @@ public class KeyguardManager {
|
||||
return response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK;
|
||||
}
|
||||
|
||||
/** Starts a session to verify lockscreen credentials provided by a remote device.
|
||||
*
|
||||
* The session and corresponding public key will be removed when
|
||||
* {@code validateRemoteLockScreen} provides a correct guess or after 10 minutes of inactivity.
|
||||
*
|
||||
* @return information necessary to perform remote lock screen credentials check, including
|
||||
|
||||
* short lived public key used to send encrypted guess and lock screen type.
|
||||
*
|
||||
* @throws IllegalStateException if lock screen is not set
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(Manifest.permission.CHECK_REMOTE_LOCKSCREEN)
|
||||
@NonNull
|
||||
public StartLockscreenValidationRequest startRemoteLockscreenValidation() {
|
||||
return mLockPatternUtils.startRemoteLockscreenValidation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies credentials guess from a remote device.
|
||||
*
|
||||
* <p>Secret must be encrypted using {@code SecureBox} library
|
||||
* with public key from {@code StartLockscreenValidationRequest}
|
||||
* and header set to {@code "encrypted_remote_credentials"} in UTF-8 encoding.
|
||||
*
|
||||
* @throws IllegalStateException if there is no active lock screen validation session or
|
||||
* there was a decryption error.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(Manifest.permission.CHECK_REMOTE_LOCKSCREEN)
|
||||
@NonNull
|
||||
public RemoteLockscreenValidationResult validateRemoteLockscreen(
|
||||
@NonNull byte[] encryptedCredential) {
|
||||
return mLockPatternUtils.validateRemoteLockscreen(encryptedCredential);
|
||||
}
|
||||
|
||||
private LockscreenCredential createLockscreenCredential(
|
||||
@LockTypes int lockType, @Nullable byte[] password) {
|
||||
if (password == null) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.app;
|
||||
import android.annotation.DurationMillisLong;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@@ -29,6 +30,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class RemoteLockscreenValidationResult implements Parcelable {
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.app;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.app.KeyguardManager.LockTypes;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
@@ -28,6 +29,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class StartLockscreenValidationRequest implements Parcelable {
|
||||
|
||||
@LockTypes
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.internal.widget;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.RemoteLockscreenValidationResult;
|
||||
import android.app.StartLockscreenValidationRequest;
|
||||
import android.app.trust.IStrongAuthTracker;
|
||||
import android.os.Bundle;
|
||||
import android.security.keystore.recovery.WrappedApplicationKey;
|
||||
@@ -93,6 +95,8 @@ interface ILockSettings {
|
||||
in byte[] recoveryKeyBlob,
|
||||
in List<WrappedApplicationKey> applicationKeys);
|
||||
void closeSession(in String sessionId);
|
||||
StartLockscreenValidationRequest startRemoteLockscreenValidation();
|
||||
RemoteLockscreenValidationResult validateRemoteLockscreen(in byte[] encryptedCredential);
|
||||
boolean hasSecureLockScreen();
|
||||
boolean tryUnlockWithCachedUnifiedChallenge(int userId);
|
||||
void removeCachedUnifiedChallenge(int userId);
|
||||
|
||||
@@ -28,6 +28,8 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.PropertyInvalidatedCache;
|
||||
import android.app.RemoteLockscreenValidationResult;
|
||||
import android.app.StartLockscreenValidationRequest;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.PasswordMetrics;
|
||||
import android.app.trust.IStrongAuthTracker;
|
||||
@@ -1822,4 +1824,29 @@ public class LockPatternUtils {
|
||||
public void removeUser(@UserIdInt int userId) {
|
||||
getLockSettingsInternal().removeUser(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a session to verify lockscreen credentials provided by a remote device.
|
||||
*/
|
||||
@NonNull
|
||||
public StartLockscreenValidationRequest startRemoteLockscreenValidation() {
|
||||
try {
|
||||
return getLockSettings().startRemoteLockscreenValidation();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies credentials guess from a remote device.
|
||||
*/
|
||||
@NonNull
|
||||
public RemoteLockscreenValidationResult validateRemoteLockscreen(
|
||||
@NonNull byte[] encryptedCredential) {
|
||||
try {
|
||||
return getLockSettings().validateRemoteLockscreen(encryptedCredential);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5975,6 +5975,11 @@
|
||||
<permission android:name="android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS"
|
||||
android:protectionLevel="signature"/>
|
||||
|
||||
<!-- @SystemApi Allows application to verify lockscreen credentials provided by a remote device.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.CHECK_REMOTE_LOCKSCREEN"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
|
||||
<!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
|
||||
<permission android:name="android.permission.MANAGE_FINGERPRINT"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
|
||||
@@ -2553,7 +2553,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
*/
|
||||
@NonNull
|
||||
public RemoteLockscreenValidationResult
|
||||
validateRemoteLockScreen2(@NonNull byte[] encryptedCredential) {
|
||||
validateRemoteLockscreen(@NonNull byte[] encryptedCredential) {
|
||||
return mRecoverableKeyStoreManager.validateRemoteLockscreen(encryptedCredential, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1126,11 +1126,10 @@ public class RecoverableKeyStoreManager {
|
||||
}
|
||||
|
||||
private void checkVerifyRemoteLockscreenPermission() {
|
||||
// TODO(b/254335492): Check new system permission
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
Manifest.permission.RECOVER_KEYSTORE,
|
||||
Manifest.permission.CHECK_REMOTE_LOCKSCREEN,
|
||||
"Caller " + Binder.getCallingUid()
|
||||
+ " doesn't have verifyRemoteLockscreen permission.");
|
||||
+ " doesn't have CHECK_REMOTE_LOCKSCREEN permission.");
|
||||
int userId = UserHandle.getCallingUserId();
|
||||
int uid = Binder.getCallingUid();
|
||||
mCleanupManager.registerRecoveryAgent(userId, uid);
|
||||
|
||||
@@ -1316,10 +1316,10 @@ public class RecoverableKeyStoreManagerTest {
|
||||
|
||||
mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
|
||||
|
||||
// TODO(b/254335492): Check new system permission
|
||||
verify(mMockContext, times(1))
|
||||
.enforceCallingOrSelfPermission(
|
||||
eq(Manifest.permission.RECOVER_KEYSTORE), any());
|
||||
eq(Manifest.permission.CHECK_REMOTE_LOCKSCREEN), any());
|
||||
mRemoteLockscreenValidationSessionStorage.finishSession(mUserId);
|
||||
}
|
||||
@Test
|
||||
public void startRemoteLockscreenValidation_returnsCredentailsType() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user