[翻譯]ICS 證書存儲實現第2部分(ICS Credential Storage Implementation, Part 2)

前言:

這是一篇關于Android安全的翻譯,這是原文地址。接上一篇翻譯。這一篇主要講述了密鑰和證書的后臺服務,IKeyChainService.aidl的實現:KeyChain.apk,以及密鑰和證書的訪問權限管理,授權數據庫的維護。

我會一段一段地復制原文,然后在下面給出翻譯,如有圖片,我會重新保存再上傳,以免出現“圖片無法顯示的情況”。


原文:

ICS Credential Storage Implementation, Part 2

December 01, 2011

譯文:

ICS 證書存儲實現第二部分
2011年12月1日

原文:

In the previous entry, we found how Android's keystore daemon manages keys and certificates, and how to connect to it using the provided keystore_cli utility. Now we will look at the intermediate layers between the OS daemon and the public KeyChain API introduced in ICS.

譯文:

前一部分,我們知道了Android的keystore守護進程是如何管理密鑰和證書的,并且使用系統提供的keystore_cli工具連接這個服務。現在我們將要看一下系統守護進程和ICS引入的 KeyChain API的中間層實現。

原文:

Browsing the android.security package, we find two AIDL files: IKeyChainService.aidl and IKeyChainAliasCallback.aidl. This is a hint that the actual key store functionality, like most Android OS services, is implemented as a remote service that the public API's bind to. IKeyChainAliasCallback is just the callback called when you select a key via KeyStore#choosePrivateKeyAlias(), so it's of little interest. IKeyChainService has the actual methods KeyChain uses to get a handle to a private key or a certificate, plus some internal API's used by the Settings and certificate installer applications. Naturally, the whole interface is marked as hidden, so SDK applications cannot directly bind to the service.

譯文:

瀏覽 android.security 包,我們找到兩個AIDL文件,IKeyChainService.aidlIKeyChainAliasCallback.aidl,這暗示著,實際的 key store 方法,像很多Android系統服務一樣,是以公開的API綁定一個遠程服務實現的。IKeyChainAliasCallback 僅僅是一個回調,在你通過KeyStore#choosePrivateKeyAlias()選中一個密鑰時調用,所以對它不感興趣。IKeyChainServiceKeyChain 實際使用的方法,用來處理一個私鑰或者證書,外加幾個內部的API,給設置和證書安裝應用使用。當然,整個接口被標記成hidden,因此SDK應用不能直接綁定到這個服務。

原文:

The IKeyChainService interface has one implementation, the KeyChainService in the KeyChain.apk system package. We find the source in packages/apps/KeyChain, so let's explore the app's configuration. Looking at the manifest reveals that it consists of three components: the KeyChainService, a KeyChainActivity, and a broadcast receiver, you guessed it, KeyChainBroadcastReceiver. The package is com.android.keychain and its sharedUserId is set to 'android.uid.system', which, as we saw in the previous article, is necessary to be able to send management commands to the native keystore daemon. Let's first examine the service.

譯文:

IKeyChainService 接口有一個實現KeyChainService, 在系統包的KeyChain.apk中。我們在packages/apps/KeyChain中找到了源碼,讓我們探索這個應用的配置。查看manifest信息,它是由三個組件構成:KeyChainServiceKeyChainActivity 和一個 broadcast receiver,你猜到了,是KeyChainBroadcastReceiver。包名是com.android.keychain,它的sharedUserId設置成了'android.uid.system',我們在前面的文章中看到了,這是向底層的keystore守護進程發送管理命令所必須的。讓我們先查看一下這個service。

原文:

As can be expected, the KeyChainService is a wrapper for the android.security.KeyStore class that directly communicates with the native keystore daemon. It provides 4 sets of functionality:

譯文:

正如所料,KeyChainServiceandroid.security.KeyStore 類的一個包裝,它和底層的 keystore 守護進程直接通信,提供了4個方法集合:

原文:

  • key store management: methods for getting private keys and certificates
  • trust store management: methods for installing and deleting CA certificates in the user trust store
  • key and trust store initialization: a reset() method that deletes all key store entries, including the master key, thus returning the key store to a 'not initialized' state; it also removes all user-installed trusted certificates
  • methods for querying and adding entries to the key access grant database (more on this later)

譯文:

  • 密鑰存儲管理:獲取私鑰和證書的方法
  • 受信任存儲管理:在用戶信受任存儲中安裝和刪除CA證書的方法
  • 密鑰和證書存儲初始化:reset()方法刪除所有密鑰存儲實體,包括master key,這讓key store回到了'not initialized'狀態,它還會刪除所有用戶安裝的受信任證書
  • 查詢和添加密鑰授權數據庫實體的方法(稍后詳細介紹)

原文:

Since the KeyChain application is running as the system user, any process that binds to its remote interface would technically be able to perform all key and trust store operations. To prevent this, the KeyChainService imposes additional access control on its users. It employs two mechanisms to achieve this: controlling access based on the caller's UID and a key access grant database. Deleting a CA certificate and resetting the key and trust stores are only allowed to the system user (those operations are typically called via the Settings app's UI, which runs as system), and installing a trusted CA certificate is only allowed to the system user or the certificate installer application (com.android.certinstaller package). Controlling access to the key store is a little bit more interesting: KeyChainService maintains a grants database (in /data/data/com.android.keychain/databases/grants.db) that maps UID's to the key aliases they are allowed to use. Let's have a look inside:

譯文:

由于KeyChain 應用以 system user(譯注:具有系統權限)運行,從技術上來說,任何綁定到它遠程接口的進程,能夠執行所有的密鑰和受信任操作。為了防止這種情況,KeyChainService給它的用戶強加了額外的訪問控制。它利用兩個機制達到這一點: 基于調用者的UID和一個密鑰訪問授權數據庫控制訪問。只允許系統用戶刪除一個CA證書和重置密鑰及受信任存儲(這些操作的典型調用是通過'設置'應用的界面,以'system'身份運行),只允許系統用戶或者證書安裝應用('com.android.certinstaller 應用')安裝一個受信任的CA證書。控制密鑰存儲的訪問比較有意思:KeyChainService 維護一個授權數據庫(在 /data/data/com.android.keychain/databases/grants.db),它把UID映射到了允許使用的密鑰別名。讓我們一探究竟:

# cd /data/data/com.android.keychain/databases
cd /data/data/com.android.keychain/databases
# ls
ls
grants.db
grants.db-journal
# sqlite3 grants.db
sqlite3 grants.db
sqlite> .schema
.schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE grants (  alias STRING NOT NULL,  uid INTEGER NOT NULL,  UNIQUE (al
ias,uid));
sqlite> select * from grants;
select * from grants;
test|10044
key1|10044

原文:

In this example, the application with UID 10044 (our test application) is granted access to the keys with the test and key1 aliases.

譯文:

在這個例子中,UID是10044的應用(我們的測試應用)被授權訪問別名為'test'和'key1'的私鑰。

原文:

Each call to getPrivateKey() or getCertificate() is subject to a check against the grants database, and results in a exception if a grant for the required alias is not found. As stated before, KeyChainService has API's for adding and querying grants, and only the system user is allowed to call them. But who is responsible for actually granting and revoking access? Remember the private key selection dialog from the first article? When you call KeyChain#choosePrivateKeyAlias(), it will start the KeyChainActivity introduced above, which will check if the key store is unlocked, and if so, show they key selection dialog. Clicking the 'Allow' button will return to the KeyChainActivity, which will then call KeyChainService#setGrant() with the selected alias, adding it to the grants database. Thus, even if the activity requesting access to a private key has the needed permissions, the user has to unlock the key store and explicitly authorize access to each individual key.

譯文:

每一次 getPrivateKey()getCertificate()調用,都要經受授權數據庫的檢查,如果沒有找到所需別名的授權,將會產生一個異常。正如前面所說,KeyChainService有添加和查詢授權的API,并且只允許system應用調用。那么誰在真正負責授權和撤消授權呢?還記得第一篇的private key selection dialog嗎?當你調用KeyChain#choosePrivateKeyAlias()時,會啟動前面介紹的 KeyChainActivity,它會檢查密鑰存儲是否解鎖,如果是,顯示密鑰選擇對話框。點擊 'Allow'按鈕,會回到KeyChainActivity,這時它用已選的別名調用KeyChainService#setGrant(),把它添加到授權數據庫。這樣,即使請求訪問一個私鑰的activity擁有所需權限,用戶不得不解鎖key store 并且顯式地給每個私鑰授權。

原文:

Besides controlling private key storage, the KeyChainService also offers trust store management by using the newly added TrustedCertificateStore class (part of libcore). This class provides both the ability to add user-installed trusted CA certificates and remove (mark as not trusted) system (pre-installed) CA's. Since the implementation is fairly complex and rather interesting, it will be the topic of another post.

譯文:

除了控制密鑰存儲,KeyChainService 還通過新添加的TrustedCertificateStore 類(libcore的一部分),提供了信任存儲管理,這個類即提供了添加用戶安裝的受信任CA證書的能力,還提供了刪除(被標記為不受信任的)系統(預先安裝的)的CA證書的能力。由于這個實現相當地復雜并且非常有趣,所以將是另一篇文章的主題。

原文:

The last component of the KeyChain app is the KeyChainBroadcastReceiver. It listens for a android.intent.action.PACKAGE_REMOVED broadcast and simply forwards control to the KeyChainService. On receiving the PACKAGE_REMOVED action, the service does some grant database maintenance: it goes through all entries and deletes those referencing packages that are no longer available (i.e., uninstalled ones). With this we now have the (almost) complete picture (click to enlarge):

譯文:

KeyChain 應用的最后一個組件是KeyChainBroadcastReceiver。 它監聽 android.intent.action.PACKAGE_REMOVED 廣播,簡單地把控制轉發到KeyChainService。當接收到 PACKAGE_REMOVED action,這個 service 做了一些授權數據庫維護:它遍歷所有的條目,刪除那些不再可用的引用package(例如,被卸載的應用)。現在我們有個(幾乎)完整的圖像(點擊放大):

keystore-diagram.png

原文:

ICS introduces a new service that grants access to both the system key store (managed by the keystore daemon) and trust store (manged by the TrustedCertificateStore class) that backs the KeyChain API exposed in the public SDK. That makes it possible to control access to keys based on both the calling process's UID and the key access grant database, thus allowing for fine-grained, user-driven control over what keys each application can access. We've discussed most of the components this framework consists of in this and the previous entry. What remains is to look into the new trust store implementation introduced in Android 4.0. That will be the focus of the next post of this series.

譯文:

ICS 引入了一個新的 service, 它給系統密鑰存儲(由keystore 守護進程管理)和受信任存儲(由 TrustedCertificateStore 類管理)授權,它是暴露在公開的SDK中的KeyChain API的后臺。它使得能夠基于調用者進程的UID和密鑰授權數據庫控制訪問。我們在這篇和前一篇文章中已經討論了很多組成這個框架的組件。剩下的是查看 Android 4.0引入的新的受信任存儲。這將是下一篇
的重點。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容