Zabezpieczanie opcji programisty

Zgodnie z dokumentem definicji zgodności Androida,producenci OEM muszą udostępnić sposób włączania tworzenia aplikacji. Udostępnianie w samochodach opcji programistycznych podobnych do tych w telefonach komórkowych sprawia jednak, że samochody te są podatne na ataki. Dostęp do opcji programistycznych może być teraz ograniczony przez producenta OEM za pomocą mechanizmu uwierzytelnionego tokena kryptograficznego. Producent OEM może:

  • określić domyślne ograniczenia przed pierwszym uruchomieniem;
  • bezpiecznie autoryzować programistów za pomocą tokenów kryptograficznych (opcjonalnie);
  • stosować zmiany ograniczeń, gdy programista jest uwierzytelniony i autoryzowany.

Na tej stronie opisujemy implementację referencyjną składającą się z aplikacji kontrolera ograniczeń debugowania i zdalnego punktu końcowego wystawcy tokenów.

Terminologia

Oprócz terminologii, na tej stronie używamy tych terminów:

  • Podpis internetowy JSON (JWS) zdefiniowany w RFC 7515.
  • Amerykański Narodowy Instytut Standaryzacji i Technologii (NIST).

Projektowanie

Producenci OEM mogą autoryzować programistów za pomocą tokenów podpisu internetowego JSON (JWS) (RFC7515). W implementacji referencyjnej tokeny dostępu są wydawane przez producentów OEM i używane przez aplikację kontrolera ograniczeń. Tokeny dostępu są odporne na ataki typu replay i fałszywe tokeny.

Rysunek 1. Projektowanie

Integracja i konfiguracja

Producenci OEM muszą określić domyślne ograniczenia przy pierwszym uruchomieniu. Producenci OEM robią to za pomocą kilku nakładek na zasoby statyczne, aby zastąpić wartości domyślne w platformie AOSP.

Domyślne ograniczenia dla użytkownika systemu bez interfejsu graficznego można skonfigurować za pomocą ciągu znaków config_defaultFirstUserRestrictions w pliku frameworks/base/core/res/res/values/config.xml, na przykład:

<!-- User restrictions set when the first user is created.
         Note: Also update appropriate overlay files. -->
    <string-array translatable="false" name="config_defaultFirstUserRestrictions">
        <item>no_debugging_features</item>
        <item>no_install_unknown_sources</item>
        <item>no_install_unknown_sources_globally</item>
    </string-array>

Domyślne ograniczenia dla kierowców, pasażerów i gości można skonfigurować w pliku frameworks/base/core/res/res/xml/config_user_types.xml. Producent OEM może nałożyć te ciągi znaków, aby ustawić domyślne ograniczenia dla każdego typu użytkownika, na przykład:

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

Kontroler preferencji numeru kompilacji

W AAOS interakcja użytkownika z wierszem preferencji Numer kompilacji w Ustawieniach jest obsługiwana przez BuildNumberPreferenceController.java znajdujący się w packages/apps/Car/Settings/src/com/android/car/settings/system/BuildNumberPreferenceController.java.

Gdy ustawione jest ograniczenie użytkownika no_debugging_features (UserManager.DISALLOW_DEBUGGING_FEATURES), BuildNumberPreferenceController pomija odliczanie do trybu programisty w wersjach produkcyjnych (user), gdy użytkownik kliknie numer kompilacji:

@Override
protected boolean handlePreferenceClicked(Preference preference) {
    if (DevelopmentSettingsUtil.isDevelopmentSettingsEnabled(getContext())) {
        return true;
    }

    // Enforce restriction on production (user) builds
    if (Build.IS_USER && mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
        showToast(R.string.dev_access_blocked_toast);
        return true;
    }

    mDevHitCountdown--;
    if (mDevHitCountdown == 0) {
        DevelopmentSettingsUtil.setDevelopmentSettingsEnabled(getContext(), true);
        showToast(R.string.show_dev_on);
    }
    return true;
}

Użycie Build.IS_USER zapewnia, że wersje produkcyjne ściśle egzekwują blokadę zabezpieczeń, a wewnętrzne zespoły inżynierów w wersjach userdebug mogą nadal uzyskiwać dostęp do opcji programistycznych za pomocą gestu 7 dotknięć na potrzeby testowania bez ręcznego zastępowania ustawień w interfejsie wiersza poleceń.

Kontroler ograniczeń debugowania

Implementacja referencyjna kontrolera ograniczeń debugowania (DRC) jest dostępna w AOSP w packages/apps/Car/DebuggingRestrictionController.

DRC umożliwia producentom OEM dynamiczne i tymczasowe zniesienie ograniczenia no_debugging_features w pojazdach produkcyjnych dla autoryzowanych techników serwisowych i programistów. Zamiast pozostawiać narzędzia do debugowania stale otwarte lub wymagać ponownego flashowania oprogramowania układowego, aplikacja DRC w pojeździe prosi użytkownika o uwierzytelnienie w backendzie producenta OEM i przesłanie podpisanego kryptograficznie tokena dostępu, aby włączyć adb i opcje programistyczne na czas sesji diagnostycznej.

Implementacja referencyjna DRC składa się z 2 głównych komponentów:

  • Aplikacja kliencka DRC w pojeździe (app/): uprzywilejowana aplikacja systemowa (z uprawnieniem MANAGE_USERS) w jednostce głównej, która uwierzytelnia programistów, sprawdza podpis certyfikatu X.509, nazwę hosta, nonce i datę ważności przychodzących tokenów JWS oraz dynamicznie przełącza ograniczenie no_debugging_features za pomocą UserManager.
  • Wystawca tokenów w chmurze (server/): usługa internetowa backendu (którą można wdrożyć jako funkcje chmury Firebase), która uwierzytelnia dane logowania programisty i wydaje podpisane kryptograficznie tokeny dostępu RS256 JWS z ograniczonym czasem ważności.

Pełne instrukcje konfiguracji, narzędzia do generowania certyfikatów i kroki wdrażania znajdziesz w przewodniku integracji kontrolera ograniczeń debugowania.

Testowanie

Google zaleca, aby producenci OEM zaczęli od implementacji referencyjnej i na jej podstawie tworzyli własne rozwiązania.

  1. Po skonfigurowaniu ograniczeń w plikach nakładek skompiluj AAOS i sprawdź zdefiniowane przepływy. Aby sprawdzić ustawienia dostępu, użyj aplikacji referencyjnej i lokalnej usługi obsługującej JWS.
  2. Opcjonalnie: skonfiguruj system tak, aby korzystał z usługi w chmurze obsługującej JWS. Sprawdź, czy w usłudze backendu obserwujesz oczekiwany przepływ.