Loading src/java/com/android/internal/telephony/CarrierInfoManager.java +61 −3 Original line number Diff line number Diff line Loading @@ -22,16 +22,20 @@ import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteConstraintException; import android.os.PersistableBundle; import android.os.UserHandle; import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.ImsiEncryptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.Pair; import com.android.internal.telephony.metrics.TelephonyMetrics; import java.security.PublicKey; import java.util.Date; /** Loading @@ -47,6 +51,10 @@ public class CarrierInfoManager { */ private static final int RESET_CARRIER_KEY_RATE_LIMIT = 12 * 60 * 60 * 1000; // Key ID used with the backup key from carrier config private static final String EPDG_BACKUP_KEY_ID = "backup_key_from_carrier_config_epdg"; private static final String WLAN_BACKUP_KEY_ID = "backup_key_from_carrier_config_wlan"; // Last time the resetCarrierKeysForImsiEncryption API was called successfully. private long mLastAccessResetCarrierKey = 0; Loading @@ -54,18 +62,21 @@ public class CarrierInfoManager { * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI. * @param keyType whether the key is being used for WLAN or ePDG. * @param context * @param fallback whether to fallback to the IMSI key info stored in carrier config * @return ImsiEncryptionInfo which contains the information, including the public key, to be * used for encryption. */ public static ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, Context context, String operatorNumeric) { String operatorNumeric, boolean fallback, int subId) { String mcc = ""; String mnc = ""; if (!TextUtils.isEmpty(operatorNumeric)) { mcc = operatorNumeric.substring(0, 3); mnc = operatorNumeric.substring(3); Log.i(LOG_TAG, "using values for mnc, mcc: " + mnc + "," + mcc); Log.i(LOG_TAG, "using values for mcc, mnc: " + mcc + "," + mnc); } else { Log.e(LOG_TAG, "Invalid networkOperator: " + operatorNumeric); return null; Loading @@ -83,8 +94,55 @@ public class CarrierInfoManager { new String[]{mcc, mnc, String.valueOf(keyType)}, null); if (findCursor == null || !findCursor.moveToFirst()) { Log.d(LOG_TAG, "No rows found for keyType: " + keyType); if (!fallback) { Log.d(LOG_TAG, "Skipping fallback logic"); return null; } // return carrier config key as fallback CarrierConfigManager carrierConfigManager = (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (carrierConfigManager == null) { Log.d(LOG_TAG, "Could not get CarrierConfigManager for backup key"); return null; } if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { Log.d(LOG_TAG, "Could not get carrier config with invalid subId"); return null; } PersistableBundle b = carrierConfigManager.getConfigForSubId(subId); if (b == null) { Log.d(LOG_TAG, "Could not get carrier config bundle for backup key"); return null; } int keyAvailabilityBitmask = b.getInt( CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT); if (!CarrierKeyDownloadManager.isKeyEnabled(keyType, keyAvailabilityBitmask)) { Log.d(LOG_TAG, "Backup key does not have matching keyType. keyType=" + keyType + " keyAvailability=" + keyAvailabilityBitmask); return null; } String keyString = null; String keyId = null; if (keyType == TelephonyManager.KEY_TYPE_EPDG) { keyString = b.getString( CarrierConfigManager.IMSI_CARRIER_PUBLIC_KEY_EPDG_STRING); keyId = EPDG_BACKUP_KEY_ID; } else if (keyType == TelephonyManager.KEY_TYPE_WLAN) { keyString = b.getString( CarrierConfigManager.IMSI_CARRIER_PUBLIC_KEY_WLAN_STRING); keyId = WLAN_BACKUP_KEY_ID; } if (TextUtils.isEmpty(keyString)) { Log.d(LOG_TAG, "Could not get carrier config key string for backup key. keyType=" + keyType); return null; } Pair<PublicKey, Long> keyInfo = CarrierKeyDownloadManager.getKeyInformation(keyString.getBytes()); return new ImsiEncryptionInfo(mcc, mnc, keyType, keyId, keyInfo.first, new Date(keyInfo.second)); } if (findCursor.getCount() > 1) { Log.e(LOG_TAG, "More than 1 row found for the keyType: " + keyType); } Loading src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java +22 −10 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ public class CarrierKeyDownloadManager extends Handler { if (carrierUsesKeys()) { if (areCarrierKeysAbsentOrExpiring()) { boolean downloadStartedSuccessfully = downloadKey(); // if the download was attemped, but not started successfully, and if carriers uses // if the download was attempted, but not started successfully, and if carriers uses // keys, we'll still want to renew the alarms, and try downloading the key a day // later. if (!downloadStartedSuccessfully) { Loading Loading @@ -231,7 +231,7 @@ public class CarrierKeyDownloadManager extends Handler { continue; } ImsiEncryptionInfo imsiEncryptionInfo = mPhone.getCarrierInfoForImsiEncryption(key_type); mPhone.getCarrierInfoForImsiEncryption(key_type, false); if (imsiEncryptionInfo != null && imsiEncryptionInfo.getExpirationTime() != null) { if (minExpirationDate > imsiEncryptionInfo.getExpirationTime().getTime()) { minExpirationDate = imsiEncryptionInfo.getExpirationTime().getTime(); Loading Loading @@ -275,7 +275,7 @@ public class CarrierKeyDownloadManager extends Handler { PendingIntent carrierKeyDownloadIntent = PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); alarmManager.set(AlarmManager.RTC_WAKEUP, minExpirationDate, carrierKeyDownloadIntent); Log.d(LOG_TAG, "setRenewelAlarm: action=" + intent.getAction() + " time=" Log.d(LOG_TAG, "setRenewalAlarm: action=" + intent.getAction() + " time=" + new Date(minExpirationDate)); } Loading Loading @@ -387,8 +387,10 @@ public class CarrierKeyDownloadManager extends Handler { mURL = b.getString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING); mAllowedOverMeteredNetwork = b.getBoolean( KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL); if (TextUtils.isEmpty(mURL) || mKeyAvailability == 0) { Log.d(LOG_TAG, "Carrier not enabled or invalid values"); if (mKeyAvailability == 0 || TextUtils.isEmpty(mURL)) { Log.d(LOG_TAG, "Carrier not enabled or invalid values. mKeyAvailability=" + mKeyAvailability + " mURL=" + mURL); return false; } for (int key_type : CARRIER_KEY_TYPES) { Loading Loading @@ -505,7 +507,16 @@ public class CarrierKeyDownloadManager extends Handler { @VisibleForTesting public boolean isKeyEnabled(int keyType) { // since keytype has values of 1, 2.... we need to subtract 1 from the keytype. int returnValue = (mKeyAvailability >> (keyType - 1)) & 1; return isKeyEnabled(keyType, mKeyAvailability); } /** * introspects the mKeyAvailability bitmask * @return true if the digit at position k is 1, else false. */ public static boolean isKeyEnabled(int keyType, int keyAvailability) { // since keytype has values of 1, 2.... we need to subtract 1 from the keytype. int returnValue = (keyAvailability >> (keyType - 1)) & 1; return (returnValue == 1) ? true : false; } Loading @@ -520,8 +531,10 @@ public class CarrierKeyDownloadManager extends Handler { if (!isKeyEnabled(key_type)) { continue; } // get encryption info with fallback=false so that we attempt a download even if there's // backup info stored in carrier config ImsiEncryptionInfo imsiEncryptionInfo = mPhone.getCarrierInfoForImsiEncryption(key_type); mPhone.getCarrierInfoForImsiEncryption(key_type, false); if (imsiEncryptionInfo == null) { Log.d(LOG_TAG, "Key not found for: " + key_type); return true; Loading Loading @@ -553,7 +566,6 @@ public class CarrierKeyDownloadManager extends Handler { // TODO(b/128550341): Implement the logic to minimize using metered network such as // LTE for downloading a certificate. request.setAllowedOverMetered(mAllowedOverMeteredNetwork); request.setVisibleInDownloadsUi(false); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); request.addRequestHeader("Accept-Encoding", "gzip"); Long carrierKeyDownloadRequestId = mDownloadManager.enqueue(request); Loading @@ -566,7 +578,7 @@ public class CarrierKeyDownloadManager extends Handler { editor.putString(MCC_MNC_PREF_TAG + slotId, mccMnc); editor.commit(); } catch (Exception e) { Log.e(LOG_TAG, "exception trying to dowload key from url: " + mURL); Log.e(LOG_TAG, "exception trying to download key from url: " + mURL); return false; } return true; Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +2 −2 Original line number Diff line number Diff line Loading @@ -1865,11 +1865,11 @@ public class GsmCdmaPhone extends Phone { } @Override public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) { public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, boolean fallback) { String operatorNumeric = TelephonyManager.from(mContext) .getSimOperatorNumericForPhone(mPhoneId); return CarrierInfoManager.getCarrierInfoForImsiEncryption(keyType, mContext, operatorNumeric); mContext, operatorNumeric, fallback, getSubId()); } @Override Loading src/java/com/android/internal/telephony/Phone.java +3 −1 Original line number Diff line number Diff line Loading @@ -3801,12 +3801,14 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { /** * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI. * @param keyType whether the key is being used for WLAN or ePDG. * @param fallback whether or not to fall back to the encryption key info stored in carrier * config * @return ImsiEncryptionInfo which includes the Key Type, the Public Key * {@link java.security.PublicKey} and the Key Identifier. * The keyIdentifier This is used by the server to help it locate the private key to * decrypt the permanent identity. */ public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) { public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, boolean fallback) { return null; } Loading src/java/com/android/internal/telephony/PhoneInternalInterface.java +2 −1 Original line number Diff line number Diff line Loading @@ -1046,12 +1046,13 @@ public interface PhoneInternalInterface { /** * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI. * @param keyType whether the key is being used for WLAN or ePDG. * @param fallback whether to fall back to the encryption key stored in carrier config * @return ImsiEncryptionInfo which includes the Key Type, the Public Key * {@link java.security.PublicKey} and the Key Identifier. * The keyIdentifier This is used by the server to help it locate the private key to * decrypt the permanent identity. */ public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType); ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, boolean fallback); /** * Resets the Carrier Keys, by deleting them from the database and sending a download intent. Loading Loading
src/java/com/android/internal/telephony/CarrierInfoManager.java +61 −3 Original line number Diff line number Diff line Loading @@ -22,16 +22,20 @@ import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteConstraintException; import android.os.PersistableBundle; import android.os.UserHandle; import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.ImsiEncryptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.Pair; import com.android.internal.telephony.metrics.TelephonyMetrics; import java.security.PublicKey; import java.util.Date; /** Loading @@ -47,6 +51,10 @@ public class CarrierInfoManager { */ private static final int RESET_CARRIER_KEY_RATE_LIMIT = 12 * 60 * 60 * 1000; // Key ID used with the backup key from carrier config private static final String EPDG_BACKUP_KEY_ID = "backup_key_from_carrier_config_epdg"; private static final String WLAN_BACKUP_KEY_ID = "backup_key_from_carrier_config_wlan"; // Last time the resetCarrierKeysForImsiEncryption API was called successfully. private long mLastAccessResetCarrierKey = 0; Loading @@ -54,18 +62,21 @@ public class CarrierInfoManager { * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI. * @param keyType whether the key is being used for WLAN or ePDG. * @param context * @param fallback whether to fallback to the IMSI key info stored in carrier config * @return ImsiEncryptionInfo which contains the information, including the public key, to be * used for encryption. */ public static ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, Context context, String operatorNumeric) { String operatorNumeric, boolean fallback, int subId) { String mcc = ""; String mnc = ""; if (!TextUtils.isEmpty(operatorNumeric)) { mcc = operatorNumeric.substring(0, 3); mnc = operatorNumeric.substring(3); Log.i(LOG_TAG, "using values for mnc, mcc: " + mnc + "," + mcc); Log.i(LOG_TAG, "using values for mcc, mnc: " + mcc + "," + mnc); } else { Log.e(LOG_TAG, "Invalid networkOperator: " + operatorNumeric); return null; Loading @@ -83,8 +94,55 @@ public class CarrierInfoManager { new String[]{mcc, mnc, String.valueOf(keyType)}, null); if (findCursor == null || !findCursor.moveToFirst()) { Log.d(LOG_TAG, "No rows found for keyType: " + keyType); if (!fallback) { Log.d(LOG_TAG, "Skipping fallback logic"); return null; } // return carrier config key as fallback CarrierConfigManager carrierConfigManager = (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (carrierConfigManager == null) { Log.d(LOG_TAG, "Could not get CarrierConfigManager for backup key"); return null; } if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { Log.d(LOG_TAG, "Could not get carrier config with invalid subId"); return null; } PersistableBundle b = carrierConfigManager.getConfigForSubId(subId); if (b == null) { Log.d(LOG_TAG, "Could not get carrier config bundle for backup key"); return null; } int keyAvailabilityBitmask = b.getInt( CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT); if (!CarrierKeyDownloadManager.isKeyEnabled(keyType, keyAvailabilityBitmask)) { Log.d(LOG_TAG, "Backup key does not have matching keyType. keyType=" + keyType + " keyAvailability=" + keyAvailabilityBitmask); return null; } String keyString = null; String keyId = null; if (keyType == TelephonyManager.KEY_TYPE_EPDG) { keyString = b.getString( CarrierConfigManager.IMSI_CARRIER_PUBLIC_KEY_EPDG_STRING); keyId = EPDG_BACKUP_KEY_ID; } else if (keyType == TelephonyManager.KEY_TYPE_WLAN) { keyString = b.getString( CarrierConfigManager.IMSI_CARRIER_PUBLIC_KEY_WLAN_STRING); keyId = WLAN_BACKUP_KEY_ID; } if (TextUtils.isEmpty(keyString)) { Log.d(LOG_TAG, "Could not get carrier config key string for backup key. keyType=" + keyType); return null; } Pair<PublicKey, Long> keyInfo = CarrierKeyDownloadManager.getKeyInformation(keyString.getBytes()); return new ImsiEncryptionInfo(mcc, mnc, keyType, keyId, keyInfo.first, new Date(keyInfo.second)); } if (findCursor.getCount() > 1) { Log.e(LOG_TAG, "More than 1 row found for the keyType: " + keyType); } Loading
src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java +22 −10 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ public class CarrierKeyDownloadManager extends Handler { if (carrierUsesKeys()) { if (areCarrierKeysAbsentOrExpiring()) { boolean downloadStartedSuccessfully = downloadKey(); // if the download was attemped, but not started successfully, and if carriers uses // if the download was attempted, but not started successfully, and if carriers uses // keys, we'll still want to renew the alarms, and try downloading the key a day // later. if (!downloadStartedSuccessfully) { Loading Loading @@ -231,7 +231,7 @@ public class CarrierKeyDownloadManager extends Handler { continue; } ImsiEncryptionInfo imsiEncryptionInfo = mPhone.getCarrierInfoForImsiEncryption(key_type); mPhone.getCarrierInfoForImsiEncryption(key_type, false); if (imsiEncryptionInfo != null && imsiEncryptionInfo.getExpirationTime() != null) { if (minExpirationDate > imsiEncryptionInfo.getExpirationTime().getTime()) { minExpirationDate = imsiEncryptionInfo.getExpirationTime().getTime(); Loading Loading @@ -275,7 +275,7 @@ public class CarrierKeyDownloadManager extends Handler { PendingIntent carrierKeyDownloadIntent = PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); alarmManager.set(AlarmManager.RTC_WAKEUP, minExpirationDate, carrierKeyDownloadIntent); Log.d(LOG_TAG, "setRenewelAlarm: action=" + intent.getAction() + " time=" Log.d(LOG_TAG, "setRenewalAlarm: action=" + intent.getAction() + " time=" + new Date(minExpirationDate)); } Loading Loading @@ -387,8 +387,10 @@ public class CarrierKeyDownloadManager extends Handler { mURL = b.getString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING); mAllowedOverMeteredNetwork = b.getBoolean( KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL); if (TextUtils.isEmpty(mURL) || mKeyAvailability == 0) { Log.d(LOG_TAG, "Carrier not enabled or invalid values"); if (mKeyAvailability == 0 || TextUtils.isEmpty(mURL)) { Log.d(LOG_TAG, "Carrier not enabled or invalid values. mKeyAvailability=" + mKeyAvailability + " mURL=" + mURL); return false; } for (int key_type : CARRIER_KEY_TYPES) { Loading Loading @@ -505,7 +507,16 @@ public class CarrierKeyDownloadManager extends Handler { @VisibleForTesting public boolean isKeyEnabled(int keyType) { // since keytype has values of 1, 2.... we need to subtract 1 from the keytype. int returnValue = (mKeyAvailability >> (keyType - 1)) & 1; return isKeyEnabled(keyType, mKeyAvailability); } /** * introspects the mKeyAvailability bitmask * @return true if the digit at position k is 1, else false. */ public static boolean isKeyEnabled(int keyType, int keyAvailability) { // since keytype has values of 1, 2.... we need to subtract 1 from the keytype. int returnValue = (keyAvailability >> (keyType - 1)) & 1; return (returnValue == 1) ? true : false; } Loading @@ -520,8 +531,10 @@ public class CarrierKeyDownloadManager extends Handler { if (!isKeyEnabled(key_type)) { continue; } // get encryption info with fallback=false so that we attempt a download even if there's // backup info stored in carrier config ImsiEncryptionInfo imsiEncryptionInfo = mPhone.getCarrierInfoForImsiEncryption(key_type); mPhone.getCarrierInfoForImsiEncryption(key_type, false); if (imsiEncryptionInfo == null) { Log.d(LOG_TAG, "Key not found for: " + key_type); return true; Loading Loading @@ -553,7 +566,6 @@ public class CarrierKeyDownloadManager extends Handler { // TODO(b/128550341): Implement the logic to minimize using metered network such as // LTE for downloading a certificate. request.setAllowedOverMetered(mAllowedOverMeteredNetwork); request.setVisibleInDownloadsUi(false); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); request.addRequestHeader("Accept-Encoding", "gzip"); Long carrierKeyDownloadRequestId = mDownloadManager.enqueue(request); Loading @@ -566,7 +578,7 @@ public class CarrierKeyDownloadManager extends Handler { editor.putString(MCC_MNC_PREF_TAG + slotId, mccMnc); editor.commit(); } catch (Exception e) { Log.e(LOG_TAG, "exception trying to dowload key from url: " + mURL); Log.e(LOG_TAG, "exception trying to download key from url: " + mURL); return false; } return true; Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +2 −2 Original line number Diff line number Diff line Loading @@ -1865,11 +1865,11 @@ public class GsmCdmaPhone extends Phone { } @Override public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) { public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, boolean fallback) { String operatorNumeric = TelephonyManager.from(mContext) .getSimOperatorNumericForPhone(mPhoneId); return CarrierInfoManager.getCarrierInfoForImsiEncryption(keyType, mContext, operatorNumeric); mContext, operatorNumeric, fallback, getSubId()); } @Override Loading
src/java/com/android/internal/telephony/Phone.java +3 −1 Original line number Diff line number Diff line Loading @@ -3801,12 +3801,14 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { /** * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI. * @param keyType whether the key is being used for WLAN or ePDG. * @param fallback whether or not to fall back to the encryption key info stored in carrier * config * @return ImsiEncryptionInfo which includes the Key Type, the Public Key * {@link java.security.PublicKey} and the Key Identifier. * The keyIdentifier This is used by the server to help it locate the private key to * decrypt the permanent identity. */ public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) { public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, boolean fallback) { return null; } Loading
src/java/com/android/internal/telephony/PhoneInternalInterface.java +2 −1 Original line number Diff line number Diff line Loading @@ -1046,12 +1046,13 @@ public interface PhoneInternalInterface { /** * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI. * @param keyType whether the key is being used for WLAN or ePDG. * @param fallback whether to fall back to the encryption key stored in carrier config * @return ImsiEncryptionInfo which includes the Key Type, the Public Key * {@link java.security.PublicKey} and the Key Identifier. * The keyIdentifier This is used by the server to help it locate the private key to * decrypt the permanent identity. */ public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType); ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, boolean fallback); /** * Resets the Carrier Keys, by deleting them from the database and sending a download intent. Loading