Guia de integração do controlador de restrição de depuração

Use as instruções desta página para integrar o DRC (Controlador de Restrição de Depuração do AAOS).

Figura 1. Exemplo de app DRC.

Arquitetura

A arquitetura de DRC é ilustrada na Figura 2. Os componentes descritos em vermelho (emissor de token e DRC) têm implementações de referência que podem ser personalizadas.

Figura 2. Arquitetura de DRC.

O que é o DRC?

A unidade principal do carro inclui o app DRC (consulte a implementação de referência em packages/apps/Car/DebuggingRestrictionController). O app de referência inclui a lógica para receber um token de acesso do emissor, validar o token e aplicar as mudanças de restrição de depuração conforme especificado no token. A lógica inclui elementos básicos de UX no carro.

O que é o emissor do token?

É um serviço da Web que emite tokens de acesso assinados criptograficamente (consulte a implementação de referência em packages/apps/Car/DebuggingRestrictionController/server). O serviço da Web de referência é uma função do Cloud do Firebase implantável. Para saber mais, consulte Cloud Functions para Firebase.

Pré-requisitos

Antes de implantar uma implementação de referência, conclua as seguintes tarefas.

Preparar certificados para assinar tokens de acesso

O emissor do token gera assinaturas JSON Web (JWS) como tokens de acesso. Para uma compatibilidade ótima, o emissor de referência só oferece suporte ao algoritmo RS256 (assinaturas RSA com SHA256). Para facilitar a rotação de chaves, use uma cadeia de certificados em vez de um único certificado para assinar tokens de acesso. Uma cadeia de certificados típica consiste em um certificado de AC raiz, um certificado de AC intermediário e um certificado de entidade final.

O certificado de entidade final que assina os tokens JWS não é diferente de um certificado TLS padrão. É possível comprar um certificado de ACs públicas, como a DigiCert, ou manter sua própria cadeia de certificados usando certificados de AC raiz autoassinados ou módulos de segurança de hardware. O certificado da entidade final precisa ser um certificado X509v3 com uma extensão de nome alternativo do assunto (SAN, na sigla em inglês). A extensão SAN contém um identificador (por exemplo, nome de host) do emissor do token. Por fim, os certificados RSA são preferidos aos certificados EC porque o emissor de tokens só oferece suporte ao RS256.

O Google fornece um script de shell para gerar certificados autoassinados em packages/apps/Car/DebuggingRestrictionController/server/genkey.sh.

Configurar o Firebase

O emissor do token de referência usa o Firebase Authentication e o Firebase Cloud Function.

Para configurar sua conta do Firebase:

  1. Para criar um projeto do Firebase, consulte Adicionar o Firebase ao seu projeto Android.
  2. Para ativar alguns autenticadores do Firebase, consulte Por onde começar com o Firebase Authentication?.
  3. Para adicionar uma função do Firebase Cloud vazia, consulte o artigo Começar a usar.
  4. Se ainda não tiver feito isso, instale o Node.js, o NPM e as ferramentas do Firebase para compilar e implantar o emissor de tokens.

Integrar o app DRC

O app de DRC de referência está localizado em packages/apps/Car/DebuggingRestrictionController. O app pode ser criado empacotado no AOSP com o Soong ou desempacotado com o Gradle.

Build agrupado

Para criar um app agrupado:

  1. Copie applicationId, projectId e apiKey de google-services.json para packages/apps/Car/DebuggingRestrictionController/soong/FirebaseApplication.java. Isso permite que o app DRC se conecte corretamente ao Firebase.
  2. Atualize estas constantes em packages/apps/Car/DebuggingRestrictionController/soong/BuildConfig.java:
    • TOKEN_USES_SELF_SIGNED_CA indica se certificados de CA raiz autoassinados são usados. Se ativado, o app DRC confia apenas no certificado de CA raiz codificado por PEM especificado em ROOT_CA_CERT.
    • TOKEN_ISSUER_API_NAME é o nome da função do Firebase Cloud e precisa corresponder à função do Cloud criada anteriormente no Console do Firebase.
    • TOKEN_ISSUER_HOSTNAME precisa corresponder ao nome alternativo do assunto no certificado da entidade final que vai assinar os tokens de acesso.
    • DRC_TEST_EMAIL e DRC_TEST_PASSWORD são credenciais de uma conta de teste opcional, que pode ser provisionada previamente no Firebase se você tiver ativado o login por e-mail/senha. Elas são usadas apenas para testes de instrumentação.

Agora o app está configurado para usar sua conta do Firebase e seus certificados. No Android 9 e versões mais recentes, é necessário configurar a lista de permissões privilegiadas. A lista de permissões precisa conter pelo menos android.permission.MANAGE_USERS. Exemplo:

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

Build sem pacote

Os builds de DRC não agrupados usam o Gradle para compilar o app.

Para criar um build sem pacotes:

  1. Confirme se você instalou o SDK do Android.
  2. Crie um arquivo de texto chamado local.properties no diretório raiz do app.
  3. Defina o local do SDK do Android:
     sdk.dir=path/to/android/sdk
  4. Para configurar o Firebase, copie google-services.json para packages/apps/Car/DebuggingRestrictionController/app. O Gradle analisa o arquivo e configura o restante automaticamente.
  5. Defina as variáveis de ambiente. Assim como nos builds agrupados, é necessário especificar:
    • $TOKEN_USES_SELF_SIGNED_CA: verdadeiro ou falso.
    • $ROOT_CA_CERT: caminho para o certificado de AC raiz codificado em PEM.
    • $TOKEN_ISSUER_API_NAME: nome da função do Cloud do Firebase
    • $TOKEN_ISSUER_HOST_NAME: SAN no certificado;
    • $DRC_TEST_EMAIL e $DRC_TEST_EMAIL: credenciais para uma conta de teste, somente builds de depuração.
  6. Para criar o app com o Gradle, execute um comando como este:
    $ ./gradlew build

Integrar o emissor do token

O emissor do token de referência é uma função do Cloud do Firebase implementada em Node.js. A função só pode ser chamada por um usuário autenticado. Antes de implantar o app, é necessário configurar a chave privada e os certificados usados para assinar os tokens JWS.

  1. Preencha um arquivo JSON com o seguinte conteúdo:
    {
        "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"
    }

    Os certificados são ordenados com o certificado de entidade final primeiro e o certificado de AC raiz no final. O período de validade é personalizável e pode ser definido para uma duração maior se um token emitido levar algum tempo para ser recebido e consumido por um app DRC. A revogação de token não é aceita.

  2. Faça upload da configuração para o Firebase:
  3. $ firebase functions:config:set api_config="$(cat YOUR_CONFIG.json)"
  4. Implante a função do Cloud do Firebase:
  5. $ firebase deploy --only functions
  6. Para gerenciar e monitorar o emissor de tokens, consulte Gerenciar a implantação de funções e as opções de ambiente de execução.

Definir restrições padrão

As restrições padrão podem ser aplicadas antes da primeira inicialização. Faça isso com sobreposições de recursos estáticos para substituir os padrões no framework do Android. As restrições podem ser aplicadas a diferentes tipos de usuários. Para saber mais sobre os diferentes tipos de usuários, consulte Suporte para vários usuários.

A restrição padrão para o usuário do sistema sem cabeça pode ser configurada com a matriz de string config_defaultFirstUserRestrictions em frameworks/base/core/res/res/values/config.xml. A configuração dessa restrição desativa automaticamente o Android Debug Bridge (adb) até que a restrição seja removida. Por exemplo:

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

As restrições padrão para usuários comuns (por exemplo, motoristas e passageiros) e convidados podem ser configuradas em frameworks/base/core/res/res/xml/config_user_types.xml. É possível sobrepor essas strings para definir as restrições padrão em cada tipo de usuário, por exemplo:

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