Guida all'integrazione del controller delle restrizioni di debug

Segui le istruzioni riportate in questa pagina per integrare il DRC (Controller per le limitazioni di debug di AAOS).

Figura 1. Esempio di app DRC.

Architettura

L'architettura DRC è illustrata nella Figura 2. I componenti evidenziati in rosso (emittente del token e DRC) sono accompagnati da implementazioni di riferimento che puoi personalizzare.

Figura 2. Architettura DRC.

Che cos'è la DRC?

L'unità principale dell'auto include l'app DRC (consulta l'implementazione di riferimento in packages/apps/Car/DebuggingRestrictionController). L'app di riferimento include la logica per ricevere un token di accesso dall'emittente del token, convalidarlo e poi applicare le modifiche alle limitazioni di debug come specificato nel token. La logica include elementi di UX di base lato auto.

Che cos'è l'emittente del token?

Si tratta di un servizio web che emette token di accesso firmati tramite crittografia (vedi l'implementazione di riferimento in packages/apps/Car/DebuggingRestrictionController/server). Il servizio web di riferimento è una funzione Cloud Firebase di cui è possibile eseguire il deployment (per saperne di più, consulta Cloud Functions per Firebase).

Prerequisiti

Prima di eseguire il deployment di un'implementazione di riferimento, assicurati di completare le seguenti attività.

Prepara i certificati per la firma dei token di accesso

L'emittente del token genera firme web JSON (JWS) come token di accesso. Per una compatibilità ottimale, l'emittente di riferimento supporta solo l'algoritmo RS256 (firme RSA con SHA256). Per facilitare la rotazione delle chiavi, utilizza una catena di certificati anziché un singolo certificato per firmare i token di accesso. Una catena di certificati tipica deve essere composta da un certificato CA radice, un certificato CA intermedio e un certificato dell'entità finale.

Il certificato dell'entità finale che firma i token JWS non è diverso da un certificato TLS standard. Puoi acquistare un certificato da CA pubbliche come DigiCert o gestire la tua catena di certificati utilizzando certificati CA radice autofirmati o moduli di sicurezza hardware. Il certificato dell'entità finale deve essere un certificato X509v3 con un'estensione Subject Alternative Name (SAN). L'estensione SAN contiene un identificatore (ad esempio il nome host) dell'emittente del token. Infine, è preferibile utilizzare i certificati RSA rispetto ai certificati EC perché l'emittente del token supporta solo RS256.

Google fornisce uno script shell per la generazione di certificati autofirmati in packages/apps/Car/DebuggingRestrictionController/server/genkey.sh.

Configura Firebase

L'emittente del token di riferimento utilizza Firebase Authentication e Firebase Cloud Function.

Per configurare il tuo account Firebase:

  1. Per creare un progetto Firebase, consulta Aggiungi Firebase al tuo progetto Android.
  2. Per attivare alcuni autenticatori Firebase, consulta Da dove inizio con Firebase Authentication?.
  3. Per aggiungere una funzione Cloud Firebase vuota, consulta Inizia.
  4. Se non l'hai già fatto, installa Node.js, NPM e gli strumenti Firebase per compilare e eseguire il deployment dell'emittente di token.

Integrare l'app DRC

L'app DRC di riferimento si trova in packages/apps/Car/DebuggingRestrictionController. L'app può essere compilata in bundle in AOSP con Soong o svincolata con Gradle.

Build in bundle

Per creare un'app in bundle:

  1. Copia applicationId, projectId e apiKey da google-services.json in packages/apps/Car/DebuggingRestrictionController/soong/FirebaseApplication.java. In questo modo, l'app DRC potrà connettersi correttamente a Firebase.
  2. Aggiorna queste costanti in packages/apps/Car/DebuggingRestrictionController/soong/BuildConfig.java:
    • TOKEN_USES_SELF_SIGNED_CA indica se vengono utilizzati certificati CA radice autofirmati. Se abilitata, l'app DRC considera attendibile solo il certificato CA radice con codifica PEM specificato in ROOT_CA_CERT.
    • TOKEN_ISSUER_API_NAME è il nome della funzione Cloud Firebase e deve corrispondere alla funzione Cloud creata in precedenza nella console Firebase.
    • TOKEN_ISSUER_HOSTNAME deve corrispondere al nome alternativo dell'oggetto nel certificato dell'entità finale che firmerà i token di accesso.
    • DRC_TEST_EMAIL e DRC_TEST_PASSWORD sono le credenziali di un account di test facoltativo, che può essere preconfigurato in Firebase se hai attivato l'accesso con email/password. Vengono utilizzati solo per i test con strumenti.

L'app è ora configurata per utilizzare il tuo account Firebase e i tuoi certificati. In Android 9 e versioni successive, devi configurare la lista consentita di autorizzazioni privilegiate. La lista consentita deve contenere almeno android.permission.MANAGE_USERS. Ad esempio:

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

Build non raggruppata

Le build DRC scomposte utilizzano Gradle per compilare l'app.

Per creare una build non raggruppata:

  1. Verifica di aver installato l'SDK per Android.
  2. Crea un file di testo denominato local.properties nella directory principale dell'app.
  3. Imposta la posizione dell'SDK Android:
     sdk.dir=path/to/android/sdk
  4. Per configurare Firebase, copia google-services.json in packages/apps/Car/DebuggingRestrictionController/app. Gradle analizza il file e configura automaticamente il resto.
  5. Definisci le variabili di ambiente. Come per le build in bundle, devi specificare:
    • $TOKEN_USES_SELF_SIGNED_CA: true o false;
    • $ROOT_CA_CERT: percorso del certificato CA radice con codifica PEM.
    • $TOKEN_ISSUER_API_NAME: il nome della funzione Cloud Firebase;
    • $TOKEN_ISSUER_HOST_NAME: SAN nel certificato.
    • $DRC_TEST_EMAIL e $DRC_TEST_EMAIL: credenziali per un account di test, solo per le build di debug.
  6. Per compilare l'app con Gradle, esegui un comando come questo:
    $ ./gradlew build

Integrare l'emittente del token

L'emittente del token di riferimento è una Funzione Cloud Firebase implementata in Node.js. La funzione può essere chiamata solo da un utente autenticato. Prima di eseguire il deployment dell'app, devi configurare la chiave privata e i certificati utilizzati per firmare i token JWS.

  1. Compila un file JSON con i seguenti contenuti:
    {
        "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"
    }

    I certificati sono ordinati con il certificato dell'entità finale in primo luogo e il certificato dell'autorità di certificazione radice alla fine. Il periodo di scadenza è personalizzabile e può essere impostato su una durata più lunga se un token emesso richiede del tempo prima di poter essere ricevuto e utilizzato da un'app DRC. La revoca del token non è supportata.

  2. Carica la configurazione su Firebase:
  3. $ firebase functions:config:set api_config="$(cat YOUR_CONFIG.json)"
  4. Esegui il deployment della funzione Cloud Firebase:
  5. $ firebase deploy --only functions
  6. Per gestire e monitorare l'emittente di token, consulta Gestire le opzioni di deployment e runtime delle funzioni.

Impostare le restrizioni predefinite

Le limitazioni predefinite possono essere applicate prima del primo avvio. Esegui questa operazione con gli overlay delle risorse statiche per sostituire i valori predefiniti nel framework Android. Le limitazioni possono essere applicate rispettivamente a diversi tipi di utenti. Per scoprire di più sui diversi tipi di utenti, consulta Assistenza multiutente.

La limitazione predefinita per l'utente di sistema headless può essere configurata con l'array di stringhe config_defaultFirstUserRestrictions in frameworks/base/core/res/res/values/config.xml. L'impostazione di questa limitazione disattiva automaticamente Android Debug Bridge (ADB) fino a quando la limitazione non viene rimossa, ad esempio:

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

Le limitazioni predefinite per gli utenti regolari (ad esempio conducenti e passeggeri) e gli ospiti possono essere configurate in frameworks/base/core/res/res/xml/config_user_types.xml. Puoi sovrapporre queste stringhe per impostare le limitazioni predefinite su ciascun tipo di utente, ad esempio:

<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>