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

Commit c047965e authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Cache SIM PIN for verification after unattended reboot."

parents ce614e30 d9476d2e
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto2";

package telephonyPinStorage;

option java_package = "com.android.internal.telephony";
option java_outer_classname = "StoredPinProto";

// Stores information about PIN of a SIM card.
message StoredPin {
    // Status of the PIN.
    enum PinStatus {
        // The PIN code is stored, but cannot be used for automatic verification.
        AVAILABLE = 1;

        // The PIN code is stored and will be usable for automatic verification after the
        // unattended reboot is completed.
        REBOOT_READY = 2;

        // The PIN code is stored and can be used for automatic verification.
        VERIFICATION_READY = 3;
    }

    // ICCID of the SIM card
    optional string iccid = 1;

    // PIN code
    optional string pin = 2;

    // Slot number
    optional int32 slot_id = 3;

    // Status of the PIN code
    optional PinStatus status = 4;

    // Boot count when the proto was generated.
    optional int32 boot_count = 5;
}

// Stores the encrypted version of StoredPin.
message EncryptedPin {
    // Encrypted StoredPin
    optional bytes encrypted_stored_pin = 1;

    // Initialization vector
    optional bytes iv = 2;
}
 No newline at end of file
+1149 −0

File added.

Preview size limit exceeded, changes collapsed.

+11 −0
Original line number Diff line number Diff line
@@ -193,6 +193,9 @@ public class UiccController extends Handler {
    private UiccStateChangedLauncher mLauncher;
    private RadioConfig mRadioConfig;

    /* The storage for the PIN codes. */
    private final PinStorage mPinStorage;

    // LocalLog buffer to hold important SIM related events for debugging
    private static LocalLog sLocalLog = new LocalLog(TelephonyUtils.IS_DEBUGGABLE ? 250 : 100);

@@ -254,6 +257,8 @@ public class UiccController extends Handler {

        PhoneConfigurationManager.registerForMultiSimConfigChange(
                this, EVENT_MULTI_SIM_CONFIG_CHANGED, null);

        mPinStorage = new PinStorage(mContext);
    }

    /**
@@ -887,6 +892,11 @@ public class UiccController extends Handler {
        return mDefaultEuiccCardId;
    }

    /** Get the {@link PinStorage}. */
    public PinStorage getPinStorage() {
        return mPinStorage;
    }

    private ArrayList<String> loadCardStrings() {
        String cardStrings =
                PreferenceManager.getDefaultSharedPreferences(mContext).getString(CARD_STRINGS, "");
@@ -1305,5 +1315,6 @@ public class UiccController extends Handler {
        }
        pw.println(" sLocalLog= ");
        sLocalLog.dump(fd, pw, args);
        mPinStorage.dump(fd, pw, args);
    }
}
+42 −1
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.internal.telephony.uicc;

import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT;
import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_FAILURE;
import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SUCCESS;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.usage.UsageStatsManager;
@@ -59,6 +63,7 @@ import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.TelephonyStatsLog;
import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
@@ -133,6 +138,7 @@ public class UiccProfile extends IccCard {
    private static final int EVENT_CARRIER_PRIVILEGES_LOADED = 13;
    private static final int EVENT_CARRIER_CONFIG_CHANGED = 14;
    private static final int EVENT_CARRIER_PRIVILEGES_TEST_OVERRIDE_SET = 15;
    private static final int EVENT_SUPPLY_ICC_PIN_DONE = 16;
    // NOTE: any new EVENT_* values must be added to eventToString.

    private TelephonyManager mTelephonyManager;
@@ -247,7 +253,7 @@ public class UiccProfile extends IccCard {
                case EVENT_CLOSE_LOGICAL_CHANNEL_DONE:
                case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
                case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
                case EVENT_SIM_IO_DONE:
                case EVENT_SIM_IO_DONE: {
                    AsyncResult ar = (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                        logWithLocalLog("handleMessage: Error in SIM access with exception "
@@ -256,6 +262,7 @@ public class UiccProfile extends IccCard {
                    AsyncResult.forMessage((Message) ar.userObj, ar.result, ar.exception);
                    ((Message) ar.userObj).sendToTarget();
                    break;
                }

                case EVENT_CARRIER_PRIVILEGES_TEST_OVERRIDE_SET:
                    if (msg.obj == null) {
@@ -267,6 +274,28 @@ public class UiccProfile extends IccCard {
                    refresh();
                    break;

                case EVENT_SUPPLY_ICC_PIN_DONE: {
                    AsyncResult ar = (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                        // An error occurred during automatic PIN verification. At this point,
                        // clear the cache and propagate the state.
                        loge("An error occurred during internal PIN verification");
                        UiccController.getInstance().getPinStorage().clearPin(mPhoneId);
                        updateExternalState();
                    } else {
                        log("Internal PIN verification was successful!");
                        // Nothing to do.
                    }
                    // Update metrics:
                    TelephonyStatsLog.write(
                            PIN_STORAGE_EVENT,
                            ar.exception != null
                                    ? PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_FAILURE
                                    : PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SUCCESS,
                            /* number_of_pins= */ 1);
                    break;
                }

                default:
                    loge("handleMessage: Unhandled message with number: " + msg.what);
                    break;
@@ -593,6 +622,17 @@ public class UiccProfile extends IccCard {
                    log("updateExternalState: card locked and records loaded; "
                            + "setting state to locked");
                }
                // If the PIN code is required and an available cached PIN is available, intercept
                // the update of external state and perform an internal PIN verification.
                if (lockedState == IccCardConstants.State.PIN_REQUIRED) {
                    String pin = UiccController.getInstance().getPinStorage().getPin(mPhoneId);
                    if (!pin.isEmpty()) {
                        log("PIN_REQUIRED[" + mPhoneId + "] - Cache present");
                        mCi.supplyIccPin(pin, mHandler.obtainMessage(EVENT_SUPPLY_ICC_PIN_DONE));
                        return;
                    }
                }

                setExternalState(lockedState);
            } else {
                if (VDBG) {
@@ -1804,6 +1844,7 @@ public class UiccProfile extends IccCard {
            case EVENT_CARRIER_CONFIG_CHANGED: return "CARRIER_CONFIG_CHANGED";
            case EVENT_CARRIER_PRIVILEGES_TEST_OVERRIDE_SET:
                return "CARRIER_PRIVILEGES_TEST_OVERRIDE_SET";
            case EVENT_SUPPLY_ICC_PIN_DONE: return "SUPPLY_ICC_PIN_DONE";
            default: return "UNKNOWN(" + event + ")";
        }
    }
+6 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.DownloadManager;
import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.app.usage.UsageStatsManager;
import android.content.BroadcastReceiver;
@@ -261,6 +262,8 @@ public class ContextFixture implements TestFixture<Context> {
                    return mTelephonyRegistryManager;
                case Context.SYSTEM_CONFIG_SERVICE:
                    return mSystemConfigManager;
                case Context.KEYGUARD_SERVICE:
                    return mKeyguardManager;
                case Context.VCN_MANAGEMENT_SERVICE:
                    return mVcnManager;
                case Context.BATTERY_STATS_SERVICE:
@@ -299,6 +302,8 @@ public class ContextFixture implements TestFixture<Context> {
                return Context.ACTIVITY_SERVICE;
            } else if (serviceClass == TelephonyManager.class) {
                return Context.TELEPHONY_SERVICE;
            } else if (serviceClass == KeyguardManager.class) {
                return Context.KEYGUARD_SERVICE;
            } else if (serviceClass == VcnManager.class) {
                return Context.VCN_MANAGEMENT_SERVICE;
            }
@@ -642,6 +647,7 @@ public class ContextFixture implements TestFixture<Context> {
        mock(TelephonyRegistryManager.class);
    private final SystemConfigManager mSystemConfigManager = mock(SystemConfigManager.class);
    private final PowerWhitelistManager mPowerWhitelistManager = mock(PowerWhitelistManager.class);
    private final KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
    private final VcnManager mVcnManager = mock(VcnManager.class);

    private final ContentProvider mContentProvider = spy(new FakeContentProvider());
Loading