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

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

ではARA-Mを作り始める準備を

前回までは、Android Secure Element CTSの実施時に必要なJava Cardアプレットを作成していました。

cheerio-the-bear.hatenablog.com

アクセスコントロール系のテストケースには、そのアプレットだけでは全然足りません。ということで、テストが期待するアクセスルールを提供できるもうひとつのアプレット、ARA-Mを作成してゆくのですが、凝ったことはしません。インストール後にコマンドでルールの追加・削除ができたりすると便利ですが、そんな機能は二の次です。今回は、期待されているルールを期待されている通りに返すだけの人を作成します。

まずはベースのアプレット

Java Cardアプレットを一度作成したこともあり、基本的なところを書くのは簡単です。SELECTされた時にそれらしいレスポンスを返すだけのスケルトン的なものを用意しました。

github.com

残念なキャストミスをひとつ、

-       short expected = command[ISO7816.OFFSET_LC];
+       short expected = (short) (command[ISO7816.OFFSET_LC] & 0xFF);

そしてもうひとつ送信バイト数を表す変数の書き間違いがあることに気付きましたが、次の次のコミットあたりで修正することにします。

-       apdu.setOutgoing();
-       apdu.setOutgoingLength(available);
-       apdu.sendBytesLong(mOutgoingData, mDataOffset, available);
+       apdu.setOutgoingLength(expected);
+       apdu.sendBytesLong(mOutgoingData, mDataOffset, expected);

Global PlatformのSecure Element Access Control仕様書に、ARA-Mの各種AIDに関する記述があります。sysmoUSIM-SJS1 4FF用ではありますが、Makefileもそれに合わせて書いたものを投入しています。

2.1. Rules in Issuer Security Domain Only

...
The ARA-M is an ordinary SE application which can be selected by a GlobalPlatform-defined AID, as follows:

  • Executable Load File AID: 'A00000015141434C'
  • Executable Module AID: 'A00000015141434C00'
  • Application AID: 'A00000015141434C00'

そして本題に入る前にUICC Carrier Privileges

今のかたちのUICC Carrier Privilegesが導入されたのは、Android 7.0の頃のことです(もう遠い目)。こちらにも同じくアクセスルールに関する要求がありますので、先にこちらに対応してしまいます。

はてな記法の表組みで綺麗に表現できないのでテキストでベタに書きますが、UICC Carrier PrivilegesではREF-AR-DOの仕様が下記のように変更・拡張されています(そして有効に活用する気配はまだみられないという)。

|REF-AR-DO|REF-DO|DeviceAppID-REF-DO|
|         |      |PKG-REF-DO        |
|         |AR-DO |PERM-AR-DO        |

標準のREF-AR-DOとの互換性を考慮し、AID-REF-DOやAPDU-AR-DOが入っていても大丈夫なように実装されていますので、下表のようなルールにしようと思います。

|REF-AR-DO|T|E2    | |                  | |                                        |
|         |L|2F    | |                  | |                                        |
|         |V|REF-DO|T|E1                | |                                        |
|         | |      |L|1E                | |                                        |
|         | |      |V|AID-REF-DO        |T|4F                                      |
|         | |      | |                  |L|06                                      |
|         | |      | |                  |V|FFFFFFFFFFFF                            |
|         | |      | |DeviceAppID-REF-DO|T|C1                                      |
|         | |      | |                  |L|14                                      |
|         | |      | |                  |V|61ED377E85D386A8DFEE6B864BD85B0BFAA5AF81|
|         | |AR-DO |T|E3                | |                                        |
|         | |      |L|0D                | |                                        |
|         | |      |V|APDU-AR-DO        |T|D0                                      |
|         | |      | |                  |L|01                                      |
|         | |      | |                  |V|01 (Always)                             |
|         | |      | |PERM-AR-DO        |T|DB                                      |
|         | |      | |                  |L|08                                      |
|         | |      | |                  |V|0000000000000001                        |
  • E22FE11E4F06FFFFFFFFFFFFC11461ED377E85D386A8DFEE6B864BD85B0BFAA5AF81E30DD00101DB080000000000000001

ここでDeviceAppID-REF-DOに持たせるハッシュ値はUICC Carrier Priviledgesのテストで期待されているもので、下記のように説明されています。

Preparing the UICC

By default, CtsCarrierApiTestCases.apk is signed by Android developer key, with hash value 61:ED:37:7E:85:D3:86:A8:DF:EE:6B:86:4B:D8:5B:0B:FA:A5:AF:81.

AID-REF-DOの'FFFFFFFFFFFF'については、UiccCarrierPrivilegeRules.javaのコメントが少し説明してくれています。下記コードのCARRIER_PRIVILEGE_AIDがそれなのですが、そんなAIDを持ったアプレットはいないはずなので、従来のGlobal PlatformのルールとUICC Carrier Privilegesのルールを共存させても問題はないということになっています。

    private static UiccAccessRule parseRefArdo(String rule) {
...
        // Allow 4F tag with a default value "FF FF FF FF FF FF" to be compatible with
        // devices having GP access control enforcer:
        //  - If no 4F tag is present, it's a CP rule.
        //  - If 4F tag has value "FF FF FF FF FF FF", it's a CP rule.
        //  - If 4F tag has other values, it's not a CP rule and Android should ignore it.
        TLV deviceDo = new TLV(TAG_DEVICE_APP_ID_REF_DO); //C1
        if (refDo.value.startsWith(TAG_AID_REF_DO)) {
            TLV cpDo = new TLV(TAG_AID_REF_DO); //4F
            String remain = cpDo.parse(refDo.value, false);
            if (!cpDo.lengthBytes.equals("06") || !cpDo.value.equals(CARRIER_PRIVILEGE_AID)
                    || remain.isEmpty() || !remain.startsWith(TAG_DEVICE_APP_ID_REF_DO)) {
                return null;
            }

PERM-AR-DOのコンテンツは適当です。64ビットを使って許可する機能の種類を詳細にコントロールすることを想定して設けられたようですが、現時点ではまだ使われていません。その他、Global Platform標準のデータオブジェクトについては、Secure Element Access Control仕様書をご覧頂きましょう。

コミットはこちら。このコミットでは要らないimport文が入っちゃってますが、すぐに使うことになります。

github.com