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

Commit c3c1d36a authored by Pankaj Kanwar's avatar Pankaj Kanwar Committed by android-build-merger
Browse files

Merge "Address IMSI privacy issues."

am: abc4c556

Change-Id: I7a8c1b77788402bc892ad2c634540049c50b0982
parents 0edc2855 abc4c556
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