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

Commit d18d1495 authored by Ricky Wai's avatar Ricky Wai Committed by android-build-merger
Browse files

Fingerprint should confirm device lock when unified

am: 53940d4c

* commit '53940d4c':
  Fingerprint should confirm device lock when unified

Change-Id: Ic4849d86219fc528862fb50e0670a243ddd60868
parents 41847fab 53940d4c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ interface ILockSettings {
    void setLockPassword(in String password, in String savedPassword, int userId);
    VerifyCredentialResponse checkPassword(in String password, int userId);
    VerifyCredentialResponse verifyPassword(in String password, long challenge, int userId);
    VerifyCredentialResponse verifyTiedProfileChallenge(String password, boolean isPattern, long challenge, int userId);
    boolean checkVoldPassword(int userId);
    boolean havePattern(int userId);
    boolean havePassword(int userId);
+37 −0
Original line number Diff line number Diff line
@@ -144,6 +144,43 @@ public final class LockPatternChecker {
        return task;
    }

    /**
     * Verify a password asynchronously.
     *
     * @param utils The LockPatternUtils instance to use.
     * @param password The password to check.
     * @param challenge The challenge to verify against the pattern.
     * @param userId The user to check against the pattern.
     * @param callback The callback to be invoked with the verification result.
     */
    public static AsyncTask<?, ?, ?> verifyTiedProfileChallenge(final LockPatternUtils utils,
            final String password,
            final boolean isPattern,
            final long challenge,
            final int userId,
            final OnVerifyCallback callback) {
        AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
            private int mThrottleTimeout;

            @Override
            protected byte[] doInBackground(Void... args) {
                try {
                    return utils.verifyTiedProfileChallenge(password, isPattern, challenge, userId);
                } catch (RequestThrottledException ex) {
                    mThrottleTimeout = ex.getTimeoutMs();
                    return null;
                }
            }

            @Override
            protected void onPostExecute(byte[] result) {
                callback.onVerified(result, mThrottleTimeout);
            }
        };
        task.execute();
        return task;
    }

    /**
     * Checks a password asynchronously.
     *
+30 −0
Original line number Diff line number Diff line
@@ -375,6 +375,36 @@ public class LockPatternUtils {
        }
    }


    /**
     * Check to see if a password matches the saved password.
     * If password matches, return an opaque attestation that the challenge
     * was verified.
     *
     * @param password The password to check.
     * @param challenge The challenge to verify against the password
     * @return the attestation that the challenge was verified, or null.
     */
    public byte[] verifyTiedProfileChallenge(String password, boolean isPattern, long challenge,
            int userId) throws RequestThrottledException {
        throwIfCalledOnMainThread();
        try {
            VerifyCredentialResponse response =
                    getLockSettings().verifyTiedProfileChallenge(password, isPattern, challenge,
                            userId);

            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
                return response.getPayload();
            } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
                throw new RequestThrottledException(response.getTimeout());
            } else {
                return null;
            }
        } catch (RemoteException re) {
            return null;
        }
    }

    /**
     * Check to see if a password matches the saved password.  If no password exists,
     * always returns true.
+31 −0
Original line number Diff line number Diff line
@@ -1110,6 +1110,37 @@ public class LockSettingsService extends ILockSettings.Stub {
        return doVerifyPassword(password, true, challenge, userId);
    }

    @Override
    public VerifyCredentialResponse verifyTiedProfileChallenge(String password, boolean isPattern,
            long challenge, int userId) throws RemoteException {
        checkPasswordReadPermission(userId);
        if (!isManagedProfileWithUnifiedLock(userId)) {
            throw new RemoteException("User id must be managed profile with unified lock");
        }
        final int parentProfileId = mUserManager.getProfileParent(userId).id;
        // Unlock parent by using parent's challenge
        final VerifyCredentialResponse parentResponse = isPattern
                ? doVerifyPattern(password, true, challenge, parentProfileId)
                : doVerifyPassword(password, true, challenge, parentProfileId);
        if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
            // Failed, just return parent's response
            return parentResponse;
        }

        try {
            // Unlock work profile, and work profile with unified lock must use password only
            return doVerifyPassword(getDecryptedPasswordForTiedProfile(userId), true,
                    challenge,
                    userId);
        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
                | NoSuchAlgorithmException | NoSuchPaddingException
                | InvalidAlgorithmParameterException | IllegalBlockSizeException
                | BadPaddingException | CertificateException | IOException e) {
            Slog.e(TAG, "Failed to decrypt child profile key", e);
            throw new RemoteException("Unable to get tied profile token");
        }
    }

    private VerifyCredentialResponse doVerifyPassword(String password, boolean hasChallenge,
            long challenge, int userId) throws RemoteException {
       checkPasswordReadPermission(userId);
+2 −10
Original line number Diff line number Diff line
@@ -947,10 +947,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
                if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
                return;
            }

            // Group ID is arbitrarily set to parent profile user ID. It just represents
            // the default fingerprints for the user.
            final int effectiveGroupId = getEffectiveUserId(groupId);
            final int realUserId = Binder.getCallingUid();

            final boolean restricted = isRestricted();
@@ -958,7 +954,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
                @Override
                public void run() {
                    MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0);
                    startAuthentication(token, opId, realUserId, effectiveGroupId, receiver,
                    startAuthentication(token, opId, realUserId, groupId, receiver,
                            flags, restricted, opPackageName);
                }
            });
@@ -993,14 +989,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
                final IFingerprintServiceReceiver receiver) {
            checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
            final boolean restricted = isRestricted();

            // Group ID is arbitrarily set to parent profile user ID. It just represents
            // the default fingerprints for the user.
            final int effectiveGroupId = getEffectiveUserId(groupId);
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    startRemove(token, fingerId, effectiveGroupId, receiver, restricted);
                    startRemove(token, fingerId, groupId, receiver, restricted);
                }
            });