use of android.app.trust.TrustManager 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;
}
Aggregations