ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LockSettingsService的setLockCredentialInternal函数详解

2021-06-22 14:04:16  阅读:292  来源: 互联网

标签:credential hash LockSettingsService userId 密码 详解 setLockCredentialInternal saved


快速链接:
.
???????????? 个人博客笔记导读目录(全部) ????????????


相关推荐:
Android Gatekeeper流程深度解剖
Android手机使用命令行增加/删除/修改密码(password/pin/pattern)
android密码解锁/指纹解锁返回的authToken深度解剖


说明: 在无特别的说明下,本文讲述得是android10.0 !

本文旨在讲解LockSettingsService的应用,先上一张系统框图,看下LockSettingsService处于什么有样子的位置
在这里插入图片描述

在android系统中的设置密码、清除密码、修改密码,都是调用到LockSettingsService.java的setLockCredential函数进行的,而setLockCredential又调用了setLockCredentialInternal,接下来我们来分析这个函数的流程

setLockCredentialInternal完成的功能有:

  • 1、如果是清除密码,即credential.isNone()==true, 则走另外一套流程;
  • 2、根据userId,读取存储的密码(其实是个hash): currentHandle = mStorage.readCredentialHash(userId)
  • 3、调用底层的enroll,将密码转换成enrolledHandle,如果enrolledHandle则说明底层出错了,则返回失败;
  • 4、将enrolledHandle转换成hash,并保存起来
  • 5、验证verifyChallenge
  • 6、setUserKeyProtection:添加一个userkey,vold使用d
  • 7、fixateNewestUserKeyAuth,也是调用到vold,fscrypt_fixate_newest_user_key_auth
  • 8、doVerifyCredential 做一次verify验证
  • 9、synchronizeUnifiedWorkChallengeForProfiles
  • 10、sendCredentialsOnChangeIfRequired
private boolean setLockCredentialInternal(LockscreenCredential credential,
        LockscreenCredential savedCredential, int userId, boolean isLockTiedToParent) {
    Objects.requireNonNull(credential);
    Objects.requireNonNull(savedCredential);
    synchronized (mSpManager) {  --------------------------------------------------//暂不介绍mSpManager机制
        if (isSyntheticPasswordBasedCredentialLocked(userId)) {
            return spBasedSetLockCredentialInternalLocked(credential, savedCredential, userId,
                    isLockTiedToParent);
        }
    }

    if (credential.isNone()) {  --------------------------------------------------//,其实就是密码类型选择了None,可以理解为,这是清除密码的流程
        clearUserKeyProtection(userId, null);
        gateKeeperClearSecureUserId(userId);
        mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
        // Still update PASSWORD_TYPE_KEY if we are running in pre-synthetic password code path,
        // since it forms part of the state that determines the credential type
        // @see getCredentialTypeInternal
        setKeyguardStoredQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
        setKeystorePassword(null, userId);
        fixateNewestUserKeyAuth(userId);
        synchronizeUnifiedWorkChallengeForProfiles(userId, null);
        setUserPasswordMetrics(LockscreenCredential.createNone(), userId);
        sendCredentialsOnChangeIfRequired(credential, userId, isLockTiedToParent);
        return true;
    }

    CredentialHash currentHandle = mStorage.readCredentialHash(userId);--------------------// 读取原来的密码
    if (isManagedProfileWithUnifiedLock(userId)) {
        // get credential from keystore when managed profile has unified lock
        if (savedCredential.isNone()) {
            try {
                //TODO: remove as part of b/80170828
                savedCredential = getDecryptedPasswordForTiedProfile(userId);
            } catch (FileNotFoundException e) {
                Slog.i(TAG, "Child profile key not found");
            } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
                    | NoSuchAlgorithmException | NoSuchPaddingException
                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
                    | BadPaddingException | CertificateException | IOException e) {
                Slog.e(TAG, "Failed to decrypt child profile key", e);
            }
        }
    } else {
        if (currentHandle.hash == null) {
            if (!savedCredential.isNone()) {
                Slog.w(TAG, "Saved credential provided, but none stored");
            }
            savedCredential.close();
            savedCredential = LockscreenCredential.createNone();
        }
    }
    synchronized (mSpManager) {
        if (shouldMigrateToSyntheticPasswordLocked(userId)) {
            initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential, userId);
            return spBasedSetLockCredentialInternalLocked(credential, savedCredential, userId,
                    isLockTiedToParent);
        }
    }
    if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
    byte[] enrolledHandle = enrollCredential(currentHandle.hash, --------------------------------// 调用底层,完成enroll
            savedCredential.getCredential(), credential.getCredential(), userId);
    if (enrolledHandle == null) {
        Slog.w(TAG, String.format("Failed to enroll %s: incorrect credential",-------------------------------// 如果底层enroll错误了,则返回failed
                credential.isPattern() ? "pattern" : "password"));
        return false;
    }
    CredentialHash willStore = CredentialHash.create(enrolledHandle, credential.getType());-----------------------------//创建hash
    mStorage.writeCredentialHash(willStore, userId);    -----------------------------//保存hash
    // Still update PASSWORD_TYPE_KEY if we are running in pre-synthetic password code path,
    // since it forms part of the state that determines the credential type
    // @see getCredentialTypeInternal
    setKeyguardStoredQuality(
            LockPatternUtils.credentialTypeToPasswordQuality(credential.getType()), userId);
    // push new secret and auth token to vold
    GateKeeperResponse gkResponse;
    try {
        gkResponse = getGateKeeperService().verifyChallenge(userId, 0, willStore.hash, -----------------------------//验证challenge
                credential.getCredential());
    } catch (RemoteException e) {
        throw new IllegalStateException("Failed to verify current credential", e);
    }
    setUserKeyProtection(userId, credential, convertResponse(gkResponse));
    fixateNewestUserKeyAuth(userId);
    // Refresh the auth token
    doVerifyCredential(credential, CHALLENGE_FROM_CALLER, 0, userId, -----------------------------//再做一次verify
            null /* progressCallback */);
    synchronizeUnifiedWorkChallengeForProfiles(userId, null);
    sendCredentialsOnChangeIfRequired(credential, userId, isLockTiedToParent);
    return true;
}

流程图
在这里插入图片描述

标签:credential,hash,LockSettingsService,userId,密码,详解,setLockCredentialInternal,saved
来源: https://blog.51cto.com/u_15278218/2936784

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有