クマは森で用を足しますか?

アウトプットは重要です。

GET DATA [All]とGET DATA [Next]の実装

ARA-Mがアクセスルールをターミナルに提供できるようにするために、GET DATAコマンドをサポートします。コマンド仕様の詳細については、Global PlatformのSecure Element Access Control仕様書4.1章を。

github.com

GET DATA [All]コマンド

GET DATA [All]コマンドは下表の通り。この表ではCLAはXXとしていますが、Global Platformのコマンドなので最上位ビットはセットされます。

CLA INS P1 P2 Le
XX CA FF 40 00

Case 2コマンドに該当しますが、GET RESPONSEコマンドを繰り返し使って長いデータを受け渡すシーケンスにはならず、いわゆる一般的なCase 2コマンドとは異なります。ひとつのブロックのデータを提供したら、ステータスワード'9000'を応答して一度終了します。後続のデータが残っているかどうかをステータスワードで認識できないターミナルは、受け取ったTLVデータの長さ情報と実際のデータ長を比較し、後述のGET DATA [Next]コマンドの送信要否を判断する必要があります。

もしアクセスルールのサイズが256バイト未満だったならステータスワード'6CYY'を使い、P3/Leバイトを'YY'に書き換えてコマンドを再送させるシーケンスになります。

Terminal Card
XX CA FF 40 00
SW (6C YY)
XX CA FF 40 YY
INS (CA) Data (..) SW (90 00)

GET DATA [Next]コマンド

GET DATA [All]で受け取ったデータで完結していない、つまり後続のデータを受信する必要があると判断したターミナルは、GET DATA [Next]コマンドを使ってそれを試みます。以降、データが長い場合には何度もこのGET DATA [Next]コマンドが使用されます。

CLA INS P1 P2 Le
XX CA FF 60 00

例えば、アクセスルールのサイズが256 + 256 + YYバイトなら、次のようなコマンドシーケンスになることが想定されます。

Terminal Card
XX CA FF 40 00
INS (CA) Data (..) SW (90 00)
XX CA FF 60 00
INS (CA) Data (..) SW (90 00)
XX CA FF 60 00
SW (6C YY)
XX CA FF 60 YY
INS (CA) Data (..) SW (90 00)

どうしてこんな仕様にしたんでしょう。

動作確認

今回の変更を加えたアプレットsysmoUSIM-SJS1 4FFにインストールし、(国内セルラー網に迷惑をかけないよう念のために)機内モードをオンしたAndroidスマートフォンに装着してみました。起動後にcom.android.phoneプロセスをdumpsysしてみると、UiccCarrierPrivilegeRulesSHA1値をひとつ抱えていることがわかります。Androidシステムの起動時にARA-Mからアクセスルールが正しく読みだされ、またそのルールのフォーマットにも誤りがなかったことが窺えます。

$ adb shell dumpsys activity service com.android.phone
...
      UiccCarrierPrivilegeRules: Handler (com.android.internal.telephony.uicc.UiccCarrierPrivilegeRules) {5dc51e4}
       mState=STATE_LOADED
       mStatusMessage='Success!'
       mAccessRules: 
        rule='cert: 61ED377E85D386A8DFEE6B864BD85B0BFAA5AF81 pkg: null access: 0'
       mUiccPkcs15: null

次はGET DATA [Refresh tag]を実装するか、それともAndroid Secure Element CTS仕様が期待するアクセスルールを書いてしまいますか。