Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abc4c556 authored by Pankaj Kanwar's avatar Pankaj Kanwar Committed by Gerrit Code Review
Browse files

Merge "Address IMSI privacy issues."

parents c015e32e 6761538c
Loading
Loading
Loading
Loading
+78 −1
Original line number Diff line number Diff line
@@ -19,8 +19,10 @@ package com.android.internal.telephony;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.os.UserHandle;
import android.provider.Telephony;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.TelephonyManager;
@@ -34,6 +36,16 @@ import java.util.Date;
 */
public class CarrierInfoManager {
    private static final String LOG_TAG = "CarrierInfoManager";
    private static final String KEY_TYPE = "KEY_TYPE";

    /*
    * Rate limit (in milliseconds) the number of times the Carrier keys can be reset.
    * Do it at most once every 12 hours.
    */
    private static final int RESET_CARRIER_KEY_RATE_LIMIT = 12 * 60 * 60 * 1000;

    // Last time the resetCarrierKeysForImsiEncryption API was called successfully.
    private long mLastAccessResetCarrierKey = 0;

    /**
     * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI.
@@ -158,4 +170,69 @@ public class CarrierInfoManager {
        updateOrInsertCarrierKey(imsiEncryptionInfo, mContext);
        //todo send key to modem. Will be done in a subsequent CL.
    }

    /**
     * Resets the Carrier Keys in the database. This involves 2 steps:
     *  1. Delete the keys from the database.
     *  2. Send an intent to download new Certificates.
     * @param context Context
     * @param mPhoneId phoneId
     *
     */
    public void resetCarrierKeysForImsiEncryption(Context context, int mPhoneId) {
        Log.i(LOG_TAG, "resetting carrier key");
        // Check rate limit.
        long now = System.currentTimeMillis();
        if (now - mLastAccessResetCarrierKey < RESET_CARRIER_KEY_RATE_LIMIT) {
            Log.i(LOG_TAG, "resetCarrierKeysForImsiEncryption: Access rate exceeded");
            return;
        }
        mLastAccessResetCarrierKey = now;
        deleteCarrierInfoForImsiEncryption(context);
        Intent resetIntent = new Intent(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD);
        resetIntent.putExtra(PhoneConstants.PHONE_KEY, mPhoneId);
        context.sendBroadcastAsUser(resetIntent, UserHandle.ALL);
    }

    /**
     * Deletes all the keys for a given Carrier from the device keystore.
     * @param context Context
     */
    public static void deleteCarrierInfoForImsiEncryption(Context context) {
        Log.i(LOG_TAG, "deleting carrier key from db");
        String mcc = "";
        String mnc = "";
        final TelephonyManager telephonyManager =
                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        String simOperator = telephonyManager.getSimOperator();
        if (!TextUtils.isEmpty(simOperator)) {
            mcc = simOperator.substring(0, 3);
            mnc = simOperator.substring(3);
        } else {
            Log.e(LOG_TAG, "Invalid networkOperator: " + simOperator);
            return;
        }
        ContentResolver mContentResolver = context.getContentResolver();
        try {
            String whereClause = "mcc=? and mnc=?";
            String[] whereArgs = new String[] { mcc, mnc };
            mContentResolver.delete(Telephony.CarrierColumns.CONTENT_URI, whereClause, whereArgs);
        } catch (Exception e) {
            Log.e(LOG_TAG, "Delete failed" + e);
        }
    }

    /**
     * Deletes all the keys from the device keystore.
     * @param context Context
     */
    public static void deleteAllCarrierKeysForImsiEncryption(Context context) {
        Log.i(LOG_TAG, "deleting ALL carrier keys from db");
        ContentResolver mContentResolver = context.getContentResolver();
        try {
            mContentResolver.delete(Telephony.CarrierColumns.CONTENT_URI, null, null);
        } catch (Exception e) {
            Log.e(LOG_TAG, "Delete failed" + e);
        }
    }
}
+26 −5
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Random;
import java.util.zip.GZIPInputStream;

/**
@@ -70,8 +71,15 @@ public class CarrierKeyDownloadManager {

    private static final int DAY_IN_MILLIS = 24 * 3600 * 1000;

    // Start trying to renew the cert X days before it expires.
    private static final int DEFAULT_RENEWAL_WINDOW_DAYS = 7;
    // Create a window prior to the key expiration, during which the cert will be
    // downloaded. Defines the start date of that window. So if the key expires on
    // Dec  21st, the start of the renewal window will be Dec 1st.
    private static final int START_RENEWAL_WINDOW_DAYS = 21;

    // This will define the end date of the window.
    private static final int END_RENEWAL_WINDOW_DAYS = 7;



    /* Intent for downloading the public key */
    private static final String INTENT_KEY_RENEWAL_ALARM_PREFIX =
@@ -111,6 +119,7 @@ public class CarrierKeyDownloadManager {
        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        filter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        filter.addAction(INTENT_KEY_RENEWAL_ALARM_PREFIX + mPhone.getPhoneId());
        filter.addAction(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD);
        mContext.registerReceiver(mBroadcastReceiver, filter, null, phone);
        mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
    }
@@ -123,6 +132,12 @@ public class CarrierKeyDownloadManager {
            if (action.equals(INTENT_KEY_RENEWAL_ALARM_PREFIX + slotId)) {
                Log.d(LOG_TAG, "Handling key renewal alarm: " + action);
                handleAlarmOrConfigChange();
            } else if (action.equals(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD)) {
                if (slotId == intent.getIntExtra(PhoneConstants.PHONE_KEY,
                        SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
                    Log.d(LOG_TAG, "Handling reset intent: " + action);
                    handleAlarmOrConfigChange();
                }
            } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
                if (slotId == intent.getIntExtra(PhoneConstants.PHONE_KEY,
                        SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
@@ -208,10 +223,16 @@ public class CarrierKeyDownloadManager {
        // set the alarm to run in a day. Else, we'll set the alarm to run 7 days prior to
        // expiration.
        if (minExpirationDate == Long.MAX_VALUE || (minExpirationDate
                < System.currentTimeMillis() + DEFAULT_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS)) {
                < System.currentTimeMillis() + END_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS)) {
            minExpirationDate = System.currentTimeMillis() + DAY_IN_MILLIS;
        } else {
            minExpirationDate = minExpirationDate - DEFAULT_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS;
            // We don't want all the phones to download the certs simultaneously, so
            // we pick a random time during the download window to avoid this situation.
            Random random = new Random();
            int max = START_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS;
            int min = END_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS;
            int randomTime = random.nextInt(max - min) + min;
            minExpirationDate = minExpirationDate - randomTime;
        }
        return minExpirationDate;
    }
@@ -478,7 +499,7 @@ public class CarrierKeyDownloadManager {
            }
            Date imsiDate = imsiEncryptionInfo.getExpirationTime();
            long timeToExpire = imsiDate.getTime() - System.currentTimeMillis();
            return (timeToExpire < DEFAULT_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS) ? true : false;
            return (timeToExpire < START_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS) ? true : false;
        }
        return false;
    }
+8 −0
Original line number Diff line number Diff line
@@ -197,6 +197,8 @@ public class GsmCdmaPhone extends Phone {
    private int mRilVersion;
    private boolean mBroadcastEmergencyCallStateChanges = false;
    private CarrierKeyDownloadManager mCDM;
    private CarrierInfoManager mCIM;

    // Constructors

    public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, int phoneId,
@@ -280,6 +282,7 @@ public class GsmCdmaPhone extends Phone {
        mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(
                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
        mCDM = new CarrierKeyDownloadManager(this);
        mCIM = new CarrierInfoManager();
    }

    private void initRatSpecific(int precisePhoneType) {
@@ -1539,6 +1542,11 @@ public class GsmCdmaPhone extends Phone {
        return mCarrerIdentifier.getCarrierName();
    }

    @Override
    public void resetCarrierKeysForImsiEncryption() {
        mCIM.resetCarrierKeysForImsiEncryption(mContext, mPhoneId);
    }

    @Override
    public String getGroupIdLevel1() {
        if (isPhoneTypeGsm()) {
+9 −0
Original line number Diff line number Diff line
@@ -3017,6 +3017,15 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        return null;
    }

    /**
     *  Resets the Carrier Keys in the database. This involves 2 steps:
     *  1. Delete the keys from the database.
     *  2. Send an intent to download new Certificates.
     */
    public void resetCarrierKeysForImsiEncryption() {
        return;
    }

    /**
     * Return if UT capability of ImsPhone is enabled or not
     */
+5 −0
Original line number Diff line number Diff line
@@ -894,4 +894,9 @@ public interface PhoneInternalInterface {
     *        decrypt the permanent identity.
     */
    public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType);

    /**
     * Resets the Carrier Keys, by deleting them from the database and sending a download intent.
     */
    public void resetCarrierKeysForImsiEncryption();
}
Loading