GET DATA [All]とGET DATA [Next]の実装
ARA-Mがアクセスルールをターミナルに提供できるようにするために、GET DATAコマンドをサポートします。コマンド仕様の詳細については、Global PlatformのSecure Element Access Control仕様書4.1章を。
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してみると、UiccCarrierPrivilegeRulesがSHA1値をひとつ抱えていることがわかります。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仕様が期待するアクセスルールを書いてしまいますか。