分享

AndroidKeyStore管理及实现

 jiffes 2018-06-19

一、   Java层代码实现及调用

1.       Apps接口调用—证书导入apk

(1)       代码路径为:packages/apps/Settings/src/com/android/settings/CredentialStorage.java

(2)       功能为UNLOCK/ INSTALL/ RESET

通过调用android.security.keystore的私有对象mkeyStore 的importkey(),put(),unlock()实现对应的功能,mkeyStore通过调用getInstance()函数进行实例化,如下图所示:

(3)       importkey函数是存储私钥文件(密码保护),put函数是存储证书文件,通过uid判断是否为SELF或者sameUser(权限控制)调用importKey时,需要传入参数为name,value,uid和flag,uid值用于认证功能,flag的作用没有理解,有懂的大牛欢迎留言指点

2.       Framwork层Service接口调用

(1)       代码路径为frameworks/base/keystore/java/android/security/keyStore.java

(2)       获取对应的KeyStore实例,通过调用Binder机制,获取名称为“android.security.keystore”的服务,并实例化私有变量mBinder,KeyStore提供了函数包括get(),put(),insert(),delete(),list(),lock(),unlock(),generate(),importkey(),sign(),vertify():

(3)       KeyStore中的importKey函数通过mBinder的importKey实现,mBinder提供了KeyStore的所有函数实现-代理模式,其中mBinder的赋值是通过ServiceManger.getServcie(“xxxx”)做为参数,通过IKeystoreService强制转换而成的:

(4)       Binder服务对应的代码路径为frameworks/base/core/java/android/security/IKeystoreService.aidl

基于该aidl文件生成对应的IKeystoreService.java 和IKeystoreService.cpp对应java bindings和C++bindings,如下图所示:

基于aidl文件生成对应的stub文件和Bnxxx. Bpxxx文件,其中Bnxxx类集成binder类,实现IKeystoreService,且提供了转换接口实现asInterface(IBinder obj):


3.       Framwork层ServiceManager接口实现

(1)       代码路径为frameworks/base/core/java/android/os/ServiceManager.java

(2)       Binder中的具体功能实现,是通过ServiceManager的getService函数获取,通过读取HashMap表来索引对应的iBinder:


(3)       所有的service的获取最终是通过ServiceManager.getIServiceManger,返回的,ServiceManager也是binder服务,最终的接口实现为BinderInternal.getContextObject()

(4)       BinderInternal.getContextObject()实现路径为framework/base/core/java/com/android/internal/os/BinderInternal.java,对应的接口实现是通过JNI实现的:

(5)       JNI的代码实现代码路径为frameworks/base/core/jni/ android_util_Binder.cpp

(6)       ProcessState的实现代码为frameworks/native/libs/binder/ProcessState.cpp:

4.       JDK层接口调用--AndroidKeyStore

 

二、   内核层代码实现及调用 – keystore1keystore2均调用keystore0的实现

1.       KeyStoreService实现—输出keystore可执行程序

Mian代码路径为system/security/keystore/keystore_main.cpp,Keymaster2支持硬件管理,则对应的keymaster2_open函数直接打开设备的相关处理函数,通过调用hw_get_module_by_class函数获取HAL接口,并且keymasterx_open函数调用的为mod->methods->open(xxx)函数:


(1)       Keymaster的实现方式分为HARDWARE_MODULE(keymaster2),VERSION_1_0(keymster1)和VERSION_0_0:

Keymaste0,keymaster1和keymaster2差异性为设备open接口,其中keymaster0和keymaster需要通过SoftKeymasterDevice进行,如下图为keymaster0,如果仅支持软件管理,则返回,否则wrapper成hardware:

 

2.       Kernel-HAL层代码实现

(1)       代码路径system/security/softkeymaster/keymaster_openssl.cpp


(2)       代码路径为system/keymaster/soft_keymaster_device.cpp,实现了keymaster1和keymaster2的初始化,这两类的master是通过SoftKeymasterDevice进行对应的指针初始化,keymaster1和keymaster2没有对应的实现函数[.methos=nullptr]:

 

3.       KeyStoreClient实现

(1)       代码路径为system/security/keystore/ keystore_cli.cpp,获取系统的service-“android.security.keystore”

(2)       代码路径为system/security/keystore/keystore_cli_v2.cpp和keystore_client_impl.cpp,对应的是版本v2客户端:

 

4.       KeyStoreServer实现

(1)       代码路径为system/security/keystore/keystore_main.cpp:

5.       硬件扩展简述

 

三、   IPC机制分析-Binder机制

1.       参考文档: mediaservice的实现及源码解析:http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html

通用的binder机制解析:http://blog.csdn.net/coding_glacier/article/details/7520199


2.       ServiceManager的代码路径为:./frameworks/native/cmds/servicemanager/service_manager.c,

(1)       打开binder驱动,判断selinux的启用情况,循环监听driver中的消息,并调用svcmgr_handler,进行处理,main函数为:

(2)       其中binder_open的功能为通过mmap方法获取一块private的内存,并通过bs->fd进行访问,返回bs(该结构体含有句柄fd, 句柄指向的mmap内存块,内存块的大小),代码路径为frameworks/native/cmds/servicemanager/binder.c,如下图所示:

(3)       通过loop监听到请求,如果请求是发送给svcmgr,则继续查看对应的服务,例如添加服务,查询服务,获取服务:


(4)       此处关注addservice的操作,调用函数为do_add_service(bs,s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid), 其中参数s为服务的名称(bio_get_string16(msg, &len)),handle为服务的处理句柄(bio_get_ref(msg))—函数的具体实现位于frameworks/native/cmds/servicemanager/binder.c中,功能类似server解析请求的数据包,添加的服务以svcinfo的信息存储到链表中svclist(该链表采用前向插入)

(5)       通过查询获取到对应的handle,然后通过回调函数,封装成replay并调用binder_send_reply发送到请求方:

3.       serviceManger做为所有服务的servcer,而特定的service是通过调用ServiceManger.addService(“xxxxx”)的方式进行服务注册,封装parcel发送请求实现对应服务的注册,代码路径为:

(1)     KeyStore以binder服务的形式提供给前端,最终导出库为libkeystore_binder,服务注册代码如下所示,代码路径为system/security/keystore/keystore_main.cpp:

(2)       keystore的注册是通过IserviceManager的addService进行注册的,通过封装对应的handler,以parcel的数据格式注册服务请求的逻辑frameworks/native/libs/binder/IServiceManager.cpp:

(3)       将本地Service的实现函数转换成对应的句柄,封装成Binder,调用的对应函数为writeStrongBinder(),最终封装发送的handler为binder->remoteBinder(),类型为BpBinder,即实际注册时service->remoteBinder():

(4)       Keystore_main为一个执行程序,通过把binder->localBinder()句柄封装在Parcel中以iocal方式驱动到servicemanger,再调用android::IPCThreadState::self()->joinThreadPool(),代码路径为frameworks/native/libs/binder/IPCThreadState.cpp,该函数为循环监听函数,通过min和mout与binderdriver进行通信:

4.       Binder的IPCThreadStat与ProcessState源码分析:

(1)       通过调用android::IPCThreadState::self()->joinThreadPool(),与Binder驱动的交互即ioctl通信交互,IPCThreadState::Self(),创建单例IPCThreadState,并且该单例是线程独享共享区的,并且对象初始化了ProcessState::self():

(2)       joinThreadPool函数,默认isMain是true,进入BC_ENTER_LOOPER循环状态:

(3)       其中processPendingDerefs()函数功能为清理掉所有的weak和strong引用:getAndExecuteCommand()功能为执行下一条命令并等待来自BinderDriver的响应


(4)       最终调用executeCommand(),基于命令码的机制进行响应数据:

 

四、   依赖机制应用-keystore Binder机制

1.       keystore注册的handler是android::sp<android::KeyStoreService>,后续的请求也是请求该handle,并转换成IKeyStoreService指针进行对应函数的调用。

2.       Binder对应的服务端接口路径为system/security/keystore/key_store_service.h,该头文件继承BnKeystoreService和IBinder,其中具体的函数实现是通过mKeyStore调用相关函数实现,BnKeystoreService的实现代码路径为system/security/keystore/include/keystore/IKeystoreService.cpp:


3.       Binder对应的客户端接口路径为system/security/keystore/ IKeystoreService.cpp中的class BpKeystoreService,

4.       Binder的请求是封装的parcel,通过循环监听进行服务的响应(不错的客户端-服务器架构)

(1)       Demo代码树为

l   IService:IInterface                      --纯虚函数(服务侧提供的功能)

l   BnService:BnInterface<IService>             -- 虚函数onTransact实现

l   BpService:BpInterface<IService>            --实现对应的服务侧函数,封装请求,并实现OnTranscat函数

l   Service:BnService<IService>                 --实现IService中的所有纯虚函数

l   Service.main                                      --调用Service的初始话和注册函数

l   Client.main                                       --调用serviceManger的getService并转换成IService接口

(2)       Keystore对应的代码树为:

l   IKeystoreService:IInterface                     --代码路径为security/keystore/include/keystore/IKeystoreSerivce.h

l   BnKeystoreService:BnInterface<IKeystoreService>--代码路径为security/keystore/include/keystore/IKeystoreSerivce.h

l   BpSrevice:BpInterface<IKeystoreService> -- 代码路径为security/keystore/IKeystoreSerivce.cpp

l   KeyStoreService:BnKeystoreService<IKeystoreService>--代码路径为system/security/keystore/ key_store_service.h

l   Keystore_main                                               --代码路径为system/security/keystore/keystore_main.cpp

l   Keystore_cli_v2                                             --代码路径为system/security/keystore/keystore_client_impl.cpp


 未完待续。。。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多