デバッグ制限コントローラ統合ガイド

AAOS のデバッグ制限コントローラ(DRC)を統合するには、次の手順を使用します。

図 1. DRC アプリの例

アーキテクチャ

DRC アーキテクチャを以下の図に示します。赤い枠線で囲まれたコンポーネント(トークン発行者とデバッグ制限コントローラ)には、カスタマイズ可能なリファレンス実装が付属しています。

図 2. DRC のアーキテクチャ

DRC とは

自動車のヘッドユニットには DRC アプリが含まれています(packages/apps/Car/DebuggingRestrictionController のリファレンス実装をご覧ください)。リファレンス アプリには、トークン発行者からアクセス トークンを受け取り、トークンを検証してから、トークンで指定されているようにデバッグ制限の変更を適用するロジックが含まれています。このロジックには、自動車側の基本的な UX 要素が含まれています。

トークン発行者とは

トークン発行者は、暗号技術を使って署名されたアクセス トークンを発行するウェブサービスです(packages/apps/Car/DebuggingRestrictionController/server のリファレンス実装をご覧ください)。参照ウェブサービスは、デプロイ可能な Firebase Cloud 関数です(詳細については、Cloud Functions for Firebaseをご覧ください)。

前提条件

リファレンス実装をデプロイする前に、次の作業を完了してください。

アクセス トークンに署名するための証明書の準備

トークン発行者は、アクセス トークンとして JSON Web Signature(JWS)を生成します。最適な互換性を確保するため、リファレンス発行者は RS256 アルゴリズム(SHA256 による RSA 署名)のみをサポートしています。鍵のローテーションを容易にするため、単一の証明書ではなく証明書チェーンを使用して、アクセス トークンに署名します。一般的な証明書チェーンは、ルート CA 証明書、中間 CA 証明書、エンド エンティティ証明書で構成されている必要があります。

JWS トークンに署名するエンド エンティティ証明書は、標準の TLS 証明書と同じです。DigiCert などのパブリック CA から証明書を購入するか、自己署名のルート CA 証明書またはハードウェア セキュリティ モジュールを使用して独自の証明書チェーンを維持することができます。エンド エンティティ証明書は、サブジェクト代替名(SAN)拡張領域がある X509v3 証明書である必要があります。SAN 拡張領域には、トークン発行者の識別子(ホスト名など)が含まれています。また、トークン発行者は RS256 のみをサポートしているため、EC 証明書よりも RSA 証明書をおすすめします。

Google では、packages/apps/Car/DebuggingRestrictionController/server/genkey.sh で自己署名の証明書を生成するためのシェル スクリプトを提供しています。

Firebase の設定

参照トークン発行者は Firebase AuthenticationFirebase Cloud 関数を使用します。

Firebase アカウントを設定するには:

  1. Firebase プロジェクトを作成するには、Android プロジェクトに Firebase を追加するをご覧ください。
  2. 一部の Firebase 認証システムを有効にするには、Firebase Authentication の開始方法をご覧ください。
  3. 空の Firebase Cloud 関数を追加するには、はじめにをご覧ください。
  4. まだ行っていない場合は、Node.js、NPM、Firebase ツールをインストールし、トークン発行者をコンパイルしてデプロイします。

DRC アプリの統合

リファレンス DRC アプリは packages/apps/Car/DebuggingRestrictionController にあります。このアプリは、Soong を使用して AOSP でバンドルしてビルドすることも、Gradle を使用してバンドルせずにビルドすることもできます。

バンドルされたビルド

バンドルされたアプリをビルドするには:

  1. applicationIdprojectIdapiKeygoogle-services.json から packages/apps/Car/DebuggingRestrictionController/soong/FirebaseApplication.java にコピーします。これにより、DRC アプリが Firebase に正しく接続できるようになります。
  2. 次の定数を packages/apps/Car/DebuggingRestrictionController/soong/BuildConfig.java で更新します。
    • TOKEN_USES_SELF_SIGNED_CA は、自己署名のルート CA 証明書が使用されているかどうかを示します。有効にすると、DRC アプリは、ROOT_CA_CERT で指定されている PEM エンコードされたルート CA 証明書のみを信頼します。
    • TOKEN_ISSUER_API_NAME は Firebase Cloud 関数の名前であり、Firebase コンソールで以前作成した Cloud 関数と一致している必要があります。
    • TOKEN_ISSUER_HOSTNAME は、アクセス トークンに署名するエンド エンティティ証明書内のサブジェクト代替名と一致している必要があります。
    • DRC_TEST_EMAILDRC_TEST_PASSWORD は、オプションのテスト アカウントの認証情報であり、メール / パスワードのログインを有効にしている場合は、Firebase に事前にプロビジョニングできます。これらはインストルメンテーション テストにのみ使用されます。

これで、Firebase アカウントと証明書を使用するようにアプリが構成されました。 Android 9 以降では、特権の許可リストへの登録を設定する必要があります。許可リストには少なくとも android.permission.MANAGE_USERS が含まれている必要があります。たとえば、次のようになります。

<permissions>
  <privapp-permissions package="com.android.car.debuggingrestrictioncontroller">
    <permission name="android.permission.INTERNET"/>
    <permission name="android.permission.MANAGE_USERS"/>
  </privapp-permissions>
</permissions>

バンドルされていないビルド

バンドルされていない DRC ビルドは、Gradle を使用してアプリをコンパイルします。

バンドルされていないビルドを作成するには:

  1. Android SDK がインストールされていることを確認します。
  2. アプリのルート ディレクトリに local.properties という名前のテキスト ファイルを作成します。
  3. Android SDK の場所を設定します。
     sdk.dir=path/to/android/sdk
    
  4. Firebase を設定するには、google-services.jsonpackages/apps/Car/DebuggingRestrictionController/app にコピーします。Gradle はファイルを解析して、残りを自動的に設定します。
  5. 環境変数を定義します。バンドルされたビルドと同様に、以下を指定する必要があります。
    • $TOKEN_USES_SELF_SIGNED_CA: true または false。
    • $ROOT_CA_CERT: PEM エンコードされたルート CA 証明書へのパス。
    • $TOKEN_ISSUER_API_NAME: Firebase Cloud 関数の名前。
    • $TOKEN_ISSUER_HOST_NAME: 証明書内の SAN。
    • $DRC_TEST_EMAIL$DRC_TEST_EMAIL: テスト アカウントの認証情報、デバッグビルドのみ。
  6. Gradle でアプリをビルドするには、次のようなコマンドを実行します。
    $ ./gradlew build
    

トークン発行者の統合

参照トークン発行者は Node.js に実装された Firebase Cloud 関数です。この関数は、認証されたユーザーだけが呼び出すことができます。アプリをデプロイする前に、JWS トークンの署名に使用する秘密鍵と証明書を設定する必要があります。

  1. JSON ファイルに次の内容を追加します。
    {
        "key": "---BEGIN PRIVATE KEY---\nRSA_PRIVATE_KEY\n-----END PRIVATE KEY-----\n",
        "certificates.0": "-----BEGIN CERTIFICATE-----\nTOKEN_SIGNING_CERT\n-----END CERTIFICATE-----\n",
        "certificates.1": "-----BEGIN CERTIFICATE-----\nINTERMEDIATE_CA_CERT\n-----END CERTIFICATE-----\n",
        "certificates.2": "-----BEGIN CERTIFICATE-----\nROOT_CA_CERT\n-----END CERTIFICATE-----\n",
        "expiration": "30m",
        "issuer": "Debugging Access Token Issuer",
        "audience": "IHU"
    }
    

    証明書は、最初にエンド エンティティ証明書、最後にルート CA 証明書の順に並んでいます。有効期限はカスタマイズ可能であり、発効されるトークンが DRC アプリで受信されて使用できるようになるまでに時間がかかる場合は、長めの時間に設定できます。トークンの失効はサポートされていません。

  2. 構成を Firebase にアップロードします。
  3. $ firebase functions:config:set api_config="$(cat YOUR_CONFIG.json)"
    
  4. Firebase Cloud 関数をデプロイします。
  5. $ firebase deploy --only functions
    
  6. トークン発行者を管理、確認するには、関数のデプロイとランタイム オプションを管理するをご覧ください。

デフォルトの制限の設定

デフォルトの制限は初回起動前に適用できます。これは、静的リソース オーバーレイを使用して行い、Android フレームワークのデフォルトをオーバーライドします。制限は、さまざまなタイプのユーザーにそれぞれ適用できます。さまざまなタイプのユーザーについては、マルチユーザー サポートをご覧ください。

ヘッドレス システム ユーザーのデフォルトの制限は、frameworks/base/core/res/res/values/config.xml 内の config_defaultFirstUserRestrictions 文字列配列で構成できます。この制限を設定すると、その制限が削除されるまで、Android Debug Bridge(ADB)が自動的に無効になります。次に例を示します。

<string-array translatable="false" name="config_defaultFirstUserRestrictions">
  <item>no_debugging_features</item>
</string-array>

通常のユーザー(ドライバーや乗客など)とゲストに対するデフォルトの制限は、frameworks/base/core/res/res/xml/config_user_types.xml で構成できます。これらの文字列をオーバーレイして、各タイプのユーザーのデフォルトの制限を設定できます。次に例を示します。

<user-types>
  <full-type name="android.os.usertype.full.SECONDARY" >
    <default-restrictions no_debugging_features="true"/>
  </full-type>
  <full-type name="android.os.usertype.full.GUEST" >
    <default-restrictions no_debugging_features="true"/>
  </full-type>
</user-types>