Search in sources :

Example 11 with VerifyCredentialResponse

use of com.android.internal.widget.VerifyCredentialResponse in project android_frameworks_base by AOSPA.

the class LockSettingsService method verifyCredential.

private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash, String credential, boolean hasChallenge, long challenge, CredentialUtil credentialUtil, ICheckCredentialProgressCallback progressCallback) throws RemoteException {
    if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
        // don't need to pass empty credentials to GateKeeper
        return VerifyCredentialResponse.OK;
    }
    if (TextUtils.isEmpty(credential)) {
        return VerifyCredentialResponse.ERROR;
    }
    if (storedHash.version == CredentialHash.VERSION_LEGACY) {
        byte[] hash = credentialUtil.toHash(credential, userId);
        if (Arrays.equals(hash, storedHash.hash)) {
            unlockKeystore(credentialUtil.adjustForKeystore(credential), userId);
            // Users with legacy credentials don't have credential-backed
            // FBE keys, so just pass through a fake token/secret
            Slog.i(TAG, "Unlocking user with fake token: " + userId);
            final byte[] fakeToken = String.valueOf(userId).getBytes();
            unlockUser(userId, fakeToken, fakeToken);
            // migrate credential to GateKeeper
            credentialUtil.setCredential(credential, null, userId);
            if (!hasChallenge) {
                notifyActivePasswordMetricsAvailable(credential, userId);
                return VerifyCredentialResponse.OK;
            }
        // Fall through to get the auth token. Technically this should never happen,
        // as a user that had a legacy credential would have to unlock their device
        // before getting to a flow with a challenge, but supporting for consistency.
        } else {
            return VerifyCredentialResponse.ERROR;
        }
    }
    VerifyCredentialResponse response;
    boolean shouldReEnroll = false;
    GateKeeperResponse gateKeeperResponse = getGateKeeperService().verifyChallenge(userId, challenge, storedHash.hash, credential.getBytes());
    int responseCode = gateKeeperResponse.getResponseCode();
    if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
        response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
    } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
        byte[] token = gateKeeperResponse.getPayload();
        if (token == null) {
            // something's wrong if there's no payload with a challenge
            Slog.e(TAG, "verifyChallenge response had no associated payload");
            response = VerifyCredentialResponse.ERROR;
        } else {
            shouldReEnroll = gateKeeperResponse.getShouldReEnroll();
            response = new VerifyCredentialResponse(token);
        }
    } else {
        response = VerifyCredentialResponse.ERROR;
    }
    if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
        if (progressCallback != null) {
            progressCallback.onCredentialVerified();
        }
        notifyActivePasswordMetricsAvailable(credential, userId);
        unlockKeystore(credential, userId);
        Slog.i(TAG, "Unlocking user " + userId + " with token length " + response.getPayload().length);
        unlockUser(userId, response.getPayload(), secretFromCredential(credential));
        if (isManagedProfileWithSeparatedLock(userId)) {
            TrustManager trustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
            trustManager.setDeviceLockedForUser(userId, false);
        }
        if (shouldReEnroll) {
            credentialUtil.setCredential(credential, credential, userId);
        }
    } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
        if (response.getTimeout() > 0) {
            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
        }
    }
    return response;
}
Also used : VerifyCredentialResponse(com.android.internal.widget.VerifyCredentialResponse) GateKeeperResponse(android.service.gatekeeper.GateKeeperResponse) TrustManager(android.app.trust.TrustManager)

Example 12 with VerifyCredentialResponse

use of com.android.internal.widget.VerifyCredentialResponse in project android_frameworks_base by DirtyUnicorns.

the class LockSettingsService method doVerifyPattern.

private VerifyCredentialResponse doVerifyPattern(String pattern, CredentialHash storedHash, boolean hasChallenge, long challenge, int userId, ICheckCredentialProgressCallback progressCallback) throws RemoteException {
    if (TextUtils.isEmpty(pattern)) {
        throw new IllegalArgumentException("Pattern can't be null or empty");
    }
    boolean shouldReEnrollBaseZero = storedHash != null && storedHash.isBaseZeroPattern;
    String patternToVerify;
    if (shouldReEnrollBaseZero) {
        patternToVerify = LockPatternUtils.patternStringToBaseZero(pattern);
    } else {
        patternToVerify = pattern;
    }
    VerifyCredentialResponse response = verifyCredential(userId, storedHash, patternToVerify, hasChallenge, challenge, new CredentialUtil() {

        @Override
        public void setCredential(String pattern, String oldPattern, int userId) throws RemoteException {
            setLockPatternInternal(pattern, oldPattern, userId);
        }

        @Override
        public byte[] toHash(String pattern, int userId) {
            return LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(pattern));
        }

        @Override
        public String adjustForKeystore(String pattern) {
            return LockPatternUtils.patternStringToBaseZero(pattern);
        }
    }, progressCallback);
    if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK && shouldReEnrollBaseZero) {
        setLockPatternInternal(pattern, patternToVerify, userId);
    }
    return response;
}
Also used : VerifyCredentialResponse(com.android.internal.widget.VerifyCredentialResponse) RemoteException(android.os.RemoteException)

Example 13 with VerifyCredentialResponse

use of com.android.internal.widget.VerifyCredentialResponse in project android_frameworks_base by DirtyUnicorns.

the class LockSettingsService method verifyCredential.

private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash, String credential, boolean hasChallenge, long challenge, CredentialUtil credentialUtil, ICheckCredentialProgressCallback progressCallback) throws RemoteException {
    if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
        // don't need to pass empty credentials to GateKeeper
        return VerifyCredentialResponse.OK;
    }
    if (TextUtils.isEmpty(credential)) {
        return VerifyCredentialResponse.ERROR;
    }
    if (storedHash.version == CredentialHash.VERSION_LEGACY) {
        byte[] hash = credentialUtil.toHash(credential, userId);
        if (Arrays.equals(hash, storedHash.hash)) {
            unlockKeystore(credentialUtil.adjustForKeystore(credential), userId);
            // Users with legacy credentials don't have credential-backed
            // FBE keys, so just pass through a fake token/secret
            Slog.i(TAG, "Unlocking user with fake token: " + userId);
            final byte[] fakeToken = String.valueOf(userId).getBytes();
            unlockUser(userId, fakeToken, fakeToken);
            // migrate credential to GateKeeper
            credentialUtil.setCredential(credential, null, userId);
            if (!hasChallenge) {
                notifyActivePasswordMetricsAvailable(credential, userId);
                return VerifyCredentialResponse.OK;
            }
        // Fall through to get the auth token. Technically this should never happen,
        // as a user that had a legacy credential would have to unlock their device
        // before getting to a flow with a challenge, but supporting for consistency.
        } else {
            return VerifyCredentialResponse.ERROR;
        }
    }
    VerifyCredentialResponse response;
    boolean shouldReEnroll = false;
    GateKeeperResponse gateKeeperResponse = getGateKeeperService().verifyChallenge(userId, challenge, storedHash.hash, credential.getBytes());
    int responseCode = gateKeeperResponse.getResponseCode();
    if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
        response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
    } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
        byte[] token = gateKeeperResponse.getPayload();
        if (token == null) {
            // something's wrong if there's no payload with a challenge
            Slog.e(TAG, "verifyChallenge response had no associated payload");
            response = VerifyCredentialResponse.ERROR;
        } else {
            shouldReEnroll = gateKeeperResponse.getShouldReEnroll();
            response = new VerifyCredentialResponse(token);
        }
    } else {
        response = VerifyCredentialResponse.ERROR;
    }
    if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
        if (progressCallback != null) {
            progressCallback.onCredentialVerified();
        }
        notifyActivePasswordMetricsAvailable(credential, userId);
        unlockKeystore(credential, userId);
        Slog.i(TAG, "Unlocking user " + userId + " with token length " + response.getPayload().length);
        unlockUser(userId, response.getPayload(), secretFromCredential(credential));
        if (isManagedProfileWithSeparatedLock(userId)) {
            TrustManager trustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
            trustManager.setDeviceLockedForUser(userId, false);
        }
        if (shouldReEnroll) {
            credentialUtil.setCredential(credential, credential, userId);
        }
    } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
        if (response.getTimeout() > 0) {
            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
        }
    }
    return response;
}
Also used : VerifyCredentialResponse(com.android.internal.widget.VerifyCredentialResponse) GateKeeperResponse(android.service.gatekeeper.GateKeeperResponse) TrustManager(android.app.trust.TrustManager)

Example 14 with VerifyCredentialResponse

use of com.android.internal.widget.VerifyCredentialResponse in project android_frameworks_base by ResurrectionRemix.

the class LockSettingsService method verifyTiedProfileChallenge.

@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, null) : doVerifyPassword(password, true, challenge, parentProfileId, null);
    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, null);
    } 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");
    }
}
Also used : InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) VerifyCredentialResponse(com.android.internal.widget.VerifyCredentialResponse) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) CertificateException(java.security.cert.CertificateException) KeyStoreException(java.security.KeyStoreException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BadPaddingException(javax.crypto.BadPaddingException) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) RemoteException(android.os.RemoteException)

Example 15 with VerifyCredentialResponse

use of com.android.internal.widget.VerifyCredentialResponse in project android_frameworks_base by crdroidandroid.

the class LockSettingsService method verifyTiedProfileChallenge.

@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, null) : doVerifyPassword(password, true, challenge, parentProfileId, null);
    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, null);
    } 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");
    }
}
Also used : InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) VerifyCredentialResponse(com.android.internal.widget.VerifyCredentialResponse) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) CertificateException(java.security.cert.CertificateException) KeyStoreException(java.security.KeyStoreException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BadPaddingException(javax.crypto.BadPaddingException) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) RemoteException(android.os.RemoteException)

Aggregations

VerifyCredentialResponse (com.android.internal.widget.VerifyCredentialResponse)15 RemoteException (android.os.RemoteException)10 TrustManager (android.app.trust.TrustManager)5 GateKeeperResponse (android.service.gatekeeper.GateKeeperResponse)5 IOException (java.io.IOException)5 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)5 InvalidKeyException (java.security.InvalidKeyException)5 KeyStoreException (java.security.KeyStoreException)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)5 UnrecoverableKeyException (java.security.UnrecoverableKeyException)5 CertificateException (java.security.cert.CertificateException)5 BadPaddingException (javax.crypto.BadPaddingException)5 IllegalBlockSizeException (javax.crypto.IllegalBlockSizeException)5 NoSuchPaddingException (javax.crypto.NoSuchPaddingException)5