Identificatori dispositivo

Android 10 modifica le autorizzazioni per gli identificatori del dispositivo in modo che tutti gli identificatori del dispositivo siano ora protetti dall'autorizzazione READ_PRIVILEGED_PHONE_STATE. Prima di Android 10, gli identificatori dispositivo permanenti (IMEI/MEID, IMSI, SIM e numero di serie della build) erano protetti dal permesso di runtime READ_PHONE_STATE. L'autorizzazione READ_PRIVILEGED_PHONE_STATE viene concessa solo alle app firmate con la chiave della piattaforma e alle app di sistema privilegiate.

Per ulteriori informazioni sui nuovi requisiti di autorizzazione, consulta le pagine Javadoc per TelephonyManager.java e Build.java.

Questa modifica interessa le seguenti API:

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Build#getSerial

Accesso per le app dell'operatore senza l'autorizzazione READ_PRIVILEGED_PHONE_STATE

Le app dell'operatore precaricate che non soddisfano i requisiti per l'autorizzazione READ_PRIVILEGED_PHONE_STATE possono implementare una delle opzioni nella tabella seguente.

Opzione Descrizione Limitazioni
Privilegi dell'operatore UICC La piattaforma Android carica i certificati memorizzati sulla UICC e concede l'autorizzazione alle app firmate da questi certificati per effettuare chiamate a metodi speciali. Gli operatori legacy hanno una popolazione di SIM ampia e consolidata, che non è facilmente aggiornabile. Inoltre, gli operatori che non dispongono dei diritti di creazione di nuove SIM (ad esempio, gli MVNO che hanno SIM emesse da MNO) non possono aggiungere o aggiornare i certificati sulle SIM.
Lista consentita OEM Gli OEM possono utilizzare OP_READ_DEVICE_IDENTIFIER per fornire identificatori di dispositivi alle app operatore consentite. Questa soluzione non è scalabile per tutti i corrieri.
Codice di allocazione del tipo (TAC) Utilizza il metodo getTypeAllocationCode, introdotto in Android 10, per esporre il TAC che restituisce le informazioni su produttore e modello. Le informazioni nel TAC non sono sufficienti per identificare un dispositivo specifico.
MSISDN Gli operatori possono utilizzare il numero di telefono (MSISDN), disponibile in TelephonyManager con il gruppo di autorizzazioni PHONE, per cercare l'IMEI nei loro sistemi di backend. Ciò richiede investimenti significativi per gli operatori. Gli operatori che mappano le chiavi di rete utilizzando l'IMSI richiedono risorse tecniche significative per passare all'MSISDN.

Tutte le app dell'operatore possono accedere agli identificatori del dispositivo aggiornando il file CarrierConfig.xml con l'hash del certificato di firma dell'app dell'operatore. Quando l'app dell'operatore chiama un metodo per leggere informazioni privilegiate, la piattaforma cerca una corrispondenza dell'hash del certificato di firma dell'app (firma SHA-1 o SHA-256 del certificato) nel file CarrierConfig.xml. Se viene trovata una corrispondenza, vengono restituite le informazioni richieste. Se non viene trovata alcuna corrispondenza, viene restituita un'eccezione di sicurezza.

Per implementare questa soluzione, gli operatori DEVONO seguire questi passaggi:

  1. Aggiorna CarrierConfig.xml con l'hash del certificato di firma dell'app dell'operatore e invia una patch.
  2. Chiedi agli OEM di aggiornare la build con QPR1+ (consigliato) OPPURE con queste patch della piattaforma richieste e con la patch contenente il file CarrierConfig.xml aggiornato del passaggio 1 precedente.

Implementazione

Aggiorna la lista consentita delle autorizzazioni privilegiate per concedere l'autorizzazione READ_PRIVILEGED_PHONE_STATE alle app privilegiate che richiedono l'accesso agli identificatori del dispositivo.

Per scoprire di più sulle liste consentite, consulta Liste consentite per le autorizzazioni privilegiate.

Per richiamare le API interessate, un'app deve soddisfare uno dei seguenti requisiti:

  • Se l'app è un'app privilegiata precaricata, ha bisogno dell'autorizzazione READ_PRIVILEGED_PHONE_STATE dichiarata in AndroidManifest.xml. L'app deve anche inserire questa autorizzazione privilegiata nella lista consentita.
  • Le app distribuite tramite Google Play richiedono privilegi dell'operatore. Scopri di più sulla concessione dei privilegi dell'operatore nella pagina Privilegi dell'operatore UICC.
  • Un'app proprietario del dispositivo o del profilo a cui è stata concessa l'autorizzazione READ_PHONE_STATE.

Un'app che non soddisfa nessuno di questi requisiti ha il seguente comportamento:

  • Se l'app ha come target versioni precedenti ad Android Q e non dispone dell'autorizzazione READ_PHONE_STATE concessa, SecurityException viene attivato. Questo è il comportamento attuale delle versioni precedenti ad Android Q, in quanto questa autorizzazione è necessaria per richiamare queste API.
  • Se l'app ha come target versioni precedenti di Android Q e dispone dell'autorizzazione READ_PHONE_STATE, riceve un valore nullo per tutte le API TelephonyManager e Build.UNKNOWN per il metodo Build#getSerial.
  • Se l'app ha come target Android 10 o versioni successive e non soddisfa uno dei nuovi requisiti, riceve un'eccezione SecurityException.

Convalida e test

La Compatibility Test Suite (CTS) include test per verificare il comportamento di accesso previsto per gli identificatori dei dispositivi per le app con privilegi dell'operatore, i proprietari di dispositivi e profili e le app che non devono avere accesso agli identificatori dei dispositivi.

I seguenti test CTS sono specifici per questa funzionalità.

cts-tradefed run cts -m CtsCarrierApiTestCases -t
    android.carrierapi.cts.CarrierApiTest

cts-tradefed run cts -m CtsTelephonyTestCases -t
    android.telephony.cts.TelephonyManagerTest

cts-tradefed run cts -m CtsTelephony3TestCases

cts-tradefed run cts -m CtsPermissionTestCases -t
    android.permission.cts.TelephonyManagerPermissionTest

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCannotGetDeviceIdentifiersWithoutPermission

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission

Domande frequenti

Quante app possono essere inserite nella lista consentita in CarrierConfig.xml per un determinato (MCC, MNC)?

Non esiste alcun limite al numero di hash dei certificati inclusi nell'array.

Quali parametri CarrierConfig in CarrierConfig.xml devo utilizzare per inserire un'app nella lista consentita?

Utilizza il seguente elemento di configurazione di primo livello all'interno di CarrierConfig.xml specifico delle opzioni AOSP che stai configurando:

<string-array name="carrier_certificate_string_array" num="2">
    <item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/>
    <item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/>
</string-array>

Esiste un modello CarrierConfig di base che posso utilizzare?

Utilizza il seguente modello. Questo deve essere aggiunto all' asset pertinente.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<carrier_config>
    <string-array name="carrier_certificate_string_array"
num="1">
        <item value="CERTIFICATE_HASH_HERE"/>
    </string-array>
</carrier_config>

La SIM dell'operatore deve essere inserita nel dispositivo per accedere agli identificatori del dispositivo?

Il CarrierConfig.xml utilizzato viene determinato in base alla SIM attualmente inserita. Ciò significa che se l'app dell'operatore X tenta di ottenere privilegi di accesso mentre è inserita la SIM dell'operatore Y, il dispositivo non troverà una corrispondenza per l'hash e restituisce un'eccezione di sicurezza.

Sui dispositivi multi-SIM, l'operatore n. 1 ha privilegi di accesso solo per la SIM n. 1 e viceversa.

In che modo gli operatori convertono il certificato di firma di un'app in un hash?

Per convertire i certificati di firma in un hash prima di aggiungerli a CarrierConfig.xml, procedi nel seguente modo:

  1. Converti la firma del certificato di firma in un array di byte utilizzando toByteArray.
  2. Utilizza MessageDigest per convertire l'array di byte in un hash di tipo byte[].
  3. Converti l'hash da byte[] in una stringa esadecimale. Per un esempio, vedi IccUtils.java.

    List<String> certHashes = new ArrayList<>();
    PackageInfo pInfo; // Carrier app PackageInfo
    MessageDigest md =
    MessageDigest.getInstance("SHA-256");
    for (Signature signature : pInfo.signatures) {
        certHashes.add(bytesToHexString(md.digest(signature.toByteArray()));
    }
  4. Se certHashes è un array di dimensioni 2 con un valore di 12345 e 54321, aggiungi quanto segue al file di configurazione dell'operatore.

    <string-array name="carrier_certificate_string_array" num="2">
        <item value="12345"/>
        <item value="54321"/>
    </string-array>