Loading src/java/com/android/internal/telephony/CarrierInfoManager.java +78 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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); } } } src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java +26 −5 Original line number Diff line number Diff line Loading @@ -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; /** Loading @@ -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 = Loading Loading @@ -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); } Loading @@ -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)) { Loading Loading @@ -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; } Loading Loading @@ -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; } Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +8 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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()) { Loading src/java/com/android/internal/telephony/Phone.java +9 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading src/java/com/android/internal/telephony/PhoneInternalInterface.java +5 −0 Original line number Diff line number Diff line Loading @@ -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
src/java/com/android/internal/telephony/CarrierInfoManager.java +78 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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); } } }
src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java +26 −5 Original line number Diff line number Diff line Loading @@ -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; /** Loading @@ -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 = Loading Loading @@ -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); } Loading @@ -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)) { Loading Loading @@ -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; } Loading Loading @@ -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; } Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +8 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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()) { Loading
src/java/com/android/internal/telephony/Phone.java +9 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
src/java/com/android/internal/telephony/PhoneInternalInterface.java +5 −0 Original line number Diff line number Diff line Loading @@ -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(); }