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

Commit d9476d2e authored by Michele Berionne's avatar Michele Berionne
Browse files

Cache SIM PIN for verification after unattended reboot.

Bug: 160784387
Test: manual
Test: atest PinStorageTest
Change-Id: Ifba934667602eda40d0c1dbe98714f210eef76d2
Merged-In: Ifba934667602eda40d0c1dbe98714f210eef76d2
(cherry picked from commit 27c78d5f)
parent 1c687c9c
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