「Opera Mobile」がAndroidに搭載されているルート証明書一覧(cacerts.bks)を使っているか調べてみる

この日記では、Androidアプリ「Opera Mobile」が Android に搭載されているルート証明書一覧*1である /system/etc/security/cacerts.bks(以降、cacerts.bks)を使っているか調べた結果と確認手順をまとめています。

結論

Opera Mobile」では Android に搭載されている cacerts.bks を使っていないと判断しました。この結果から、cacerts.bks に不正なルート証明書が含まれていても「Opera Mobile」はそのルート証明書を(証明書の検証に)使用しないと言えます。

以下にこの日記を書いた「背景」と結論に至った「確認手順」をまとめています。興味のある方だけどうぞ。

背景

2011年8月、DigiNotar社でサーバ証明書が不正に発行されてしまう事件が発覚しました。この事件の対処として、Windowsや主要なブラウザ(Mozilla Firefox, Opera)が DigiNotar社のルート証明書を「信頼できない証明書」とするアップデートを提供しました(Wikipedia 記事)。
しかし、Android 端末では cacerts.bks に DigiNotar社のルート証明書が登録されている端末があるようです(参考情報を参照)。Android 端末には容易にアップデートを提供できない事情*2があると言われていることから、DigiNotar社のルート証明書を削除する対処が難しいと推測します。
ここで「ブラウザアプリがすべて Android に搭載されているルート証明書一覧を使うのか」という疑問がわきました。Windows で動作するブラウザでも Mozilla FirefoxOpera は(Windows とは別に)独自に管理しているルート証明書一覧を使っています。このことから、「Android アプリ「Opera Mobile」や「Firefox」でも独自に管理しているルート証明書一覧を使っているのではないか?」と考えました。この疑問を解消するために、例として Android アプリ「Opera Mobile」が実際に Android 端末に搭載しているルート証明書一覧を使っているか調べてみました。

確認手順

次の手順で、「Opera Mobile」が cacerts.bks を使っているか調べました。

Androidエミュレータ、アプリのバージョンは次の表の通りです。この手順を実施すると Android 端末の動作に支障が出る可能性があることから、Android 端末ではなく Android エミュレータを使いました。この手順にて https://www.jpcert.or.jp/ にアクセスしていますが、特に意図して選択したわけではありません(思いつきです:))。通常証明書関連の警告が出ずに閲覧できる https サイトならどこでもよいと思っています。

エミュレータAndroidアプリ名 バージョン*3
Androidエミュレータ 2.2
ブラウザ 2.2
Opera Mobile 11.10.1109081720
手順1

まず「ブラウザ」、「Opera Mobile」で https://www.jpcert.or.jp を閲覧します。それぞれのアプリともに証明書に関連する警告が出ずに閲覧できることを確認しました(下図)。

手順2

続いて、Android エミュレータから /system/etc/security/cacerts.bks を削除します。この削除手順については、id:papaking_ken さんのブログ記事 を参考にさせていただきました。お手元の環境で同様の手順を実施する場合、各コマンドにパスが通っていることなど適宜置き換えてください。

(1) 「-partion-size」オプションに 128 を設定して、Android エミュレータを起動する。
$>emulator.exe -avd Android2.2 -partition-size 128

(2) /system 領域の書き込みを許可するため、「adb remount」コマンドを実行する。
$>adb -e remount
remount succeeded

(3) /system/etc/security/cacerts.bks を削除する。
$>adb -e shell
# cd /system/etc/security
cd /system/etc/security
# ls
ls
otacerts.zip
cacerts.bks
# rm cacerts.bks
rm cacerts.bks
# ls
ls
otacerts.zip

(4) /system 領域の YAFFS2 イメージを取得する。
(4)-1. mkfs.yaffs2.arm を Android エミュレータに転送する。
$>adb -e push mkfs.yaffs2.arm /data/local/
105 KB/s (463072 bytes in 4.296s)

(4)-2. mkfs.yaffs2.arm で YAFFS2 イメージを作成する。
$>adb -e shell
# cd /data/local
cd /data/local
# ls
ls
mkfs.yaffs2.arm
tmp
# chmod 755 mkfs.yaffs2.arm
chmod 755 mkfs.yaffs2.arm
# /data/local/mkfs.yaffs2.arm /system /sdcard/system.img
/data/local/mkfs.yaffs2.arm /system /sdcard/system.img
mkfs.yaffs2: Android YAFFS2 Tool,Build by PowerGUI
            at http://www.openhandsetalliance.org.cn
Building...
Build Ok.
# exit
exit

(4)-3. 作成したイメージを PC に転送する。
$>adb -e pull /sdcard/system.img .
63 KB/s (81054336 bytes in 1247.359s)

(5). 「-system」オプションに (4) で作成したイメージを設定して、Android エミュレータを起動する。
$>emulator.exe -avd Android2.2 -system system.img


(5) で起動した Android エミュレータに「adb shell」で接続すると、/system/etc/security/cacerts.bks がないことが確認できます。

$>adb -e shell
# cd /system/etc/security/
cd /system/etc/security/
# ls
ls
otacerts.zip
#
手順3

cacerts.bks を削除した状態で、改めて「ブラウザ」、「Opera Mobile」で https://www.jpcert.or.jp を閲覧します。この結果「ブラウザ」は異常終了してしまうこと、「Opera Mobile」は手順1と同様に閲覧できることを確認しました(下図)。

「ブラウザ」が異常終了したとき、「adb logcat」コマンドでログを確認してみると以下のようなエラーが記録されていました。エラー内容から「ブラウザ」が SSL サーバ証明書を検証するところでエラーが生じていると推測します。手順1 と手順3では cacerts.bks の有無しか違いがないことから、cacerts.bks がないことで SSL サーバ証明書の検証に失敗したと判断できます。

E/AndroidRuntime(  242): FATAL EXCEPTION: http3
E/AndroidRuntime(  242): java.lang.NullPointerException
E/AndroidRuntime(  242):        at android.net.http.CertificateChainValidator.doHandshakeAndValidateServerCertificates(CertificateChainValidator.java:194)
E/AndroidRuntime(  242):        at android.net.http.HttpsConnection.openConnection(HttpsConnection.java:308)
E/AndroidRuntime(  242):        at android.net.http.Connection.openHttpConnection(Connection.java:358)
E/AndroidRuntime(  242):        at android.net.http.Connection.processRequests(Connection.java:219)
E/AndroidRuntime(  242):        at android.net.http.ConnectionThread.run(ConnectionThread.java:113)
W/ActivityManager(   59):   Force finishing activity com.android.browser/.BrowserActivity

一方「Opera Mobile」では手順1, 手順3の結果に違いがありません。cacerts.bks の有無に関わらず結果が変わらないことから、「Opera Mobile」は Android に搭載されているルート証明書一覧(cacerts.bks)を使っていないと判断しました。

*1:http://developer.android.com/ で「cacerts.bks」を検索しても具体的な情報がありませんでした。インターネット上に cacerts.bks がルート証明書一覧であることを示す情報が多いことから、この認識が妥当と考えています。

*2:IPA『スマートフォンへの脅威と対策』に関するレポートを参照してください。

*3:アプリのバージョン情報は、[設定]-[アプリケーション]-[アプリケーションの管理]で確認したバージョンを掲載しています。