1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.pm; 18 19 import android.content.pm.PackageManager; 20 import android.util.SparseBooleanArray; 21 22 import com.android.server.pm.PackageManagerService.VerificationParams; 23 24 /** 25 * Tracks the package verification state for a particular package. Each package verification has a 26 * required verifier and zero or more sufficient verifiers. Only one of the sufficient verifier list 27 * must return affirmative to allow the package to be considered verified. If there are zero 28 * sufficient verifiers, then package verification is considered complete. 29 */ 30 class PackageVerificationState { 31 private final VerificationParams mParams; 32 33 private final SparseBooleanArray mSufficientVerifierUids; 34 35 private int mRequiredVerifierUid; 36 37 private boolean mSufficientVerificationComplete; 38 39 private boolean mSufficientVerificationPassed; 40 41 private boolean mRequiredVerificationComplete; 42 43 private boolean mRequiredVerificationPassed; 44 45 private boolean mExtendedTimeout; 46 47 private boolean mIntegrityVerificationComplete; 48 49 /** 50 * Create a new package verification state where {@code requiredVerifierUid} is the user ID for 51 * the package that must reply affirmative before things can continue. 52 */ PackageVerificationState(VerificationParams params)53 PackageVerificationState(VerificationParams params) { 54 mParams = params; 55 mSufficientVerifierUids = new SparseBooleanArray(); 56 mExtendedTimeout = false; 57 } 58 getVerificationParams()59 VerificationParams getVerificationParams() { 60 return mParams; 61 } 62 63 /** Sets the user ID of the required package verifier. */ setRequiredVerifierUid(int uid)64 void setRequiredVerifierUid(int uid) { 65 mRequiredVerifierUid = uid; 66 } 67 68 /** 69 * Add a verifier which is added to our sufficient list. 70 * 71 * @param uid user ID of sufficient verifier 72 */ addSufficientVerifier(int uid)73 void addSufficientVerifier(int uid) { 74 mSufficientVerifierUids.put(uid, true); 75 } 76 77 /** 78 * Should be called when a verification is received from an agent so the state of the package 79 * verification can be tracked. 80 * 81 * @param uid user ID of the verifying agent 82 * @return {@code true} if the verifying agent actually exists in our list 83 */ setVerifierResponse(int uid, int code)84 boolean setVerifierResponse(int uid, int code) { 85 if (uid == mRequiredVerifierUid) { 86 mRequiredVerificationComplete = true; 87 switch (code) { 88 case PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT: 89 mSufficientVerifierUids.clear(); 90 // fall through 91 case PackageManager.VERIFICATION_ALLOW: 92 mRequiredVerificationPassed = true; 93 break; 94 default: 95 mRequiredVerificationPassed = false; 96 } 97 return true; 98 } else { 99 if (mSufficientVerifierUids.get(uid)) { 100 if (code == PackageManager.VERIFICATION_ALLOW) { 101 mSufficientVerificationComplete = true; 102 mSufficientVerificationPassed = true; 103 } 104 105 mSufficientVerifierUids.delete(uid); 106 if (mSufficientVerifierUids.size() == 0) { 107 mSufficientVerificationComplete = true; 108 } 109 110 return true; 111 } 112 } 113 114 return false; 115 } 116 117 /** 118 * Returns whether verification is considered complete. This means that the required verifier 119 * and at least one of the sufficient verifiers has returned a positive verification. 120 * 121 * @return {@code true} when verification is considered complete 122 */ isVerificationComplete()123 boolean isVerificationComplete() { 124 if (!mRequiredVerificationComplete) { 125 return false; 126 } 127 128 if (mSufficientVerifierUids.size() == 0) { 129 return true; 130 } 131 132 return mSufficientVerificationComplete; 133 } 134 135 /** 136 * Returns whether installation should be allowed. This should only be called after {@link 137 * #isVerificationComplete()} returns {@code true}. 138 * 139 * @return {@code true} if installation should be allowed 140 */ isInstallAllowed()141 boolean isInstallAllowed() { 142 if (!mRequiredVerificationPassed) { 143 return false; 144 } 145 146 if (mSufficientVerificationComplete) { 147 return mSufficientVerificationPassed; 148 } 149 150 return true; 151 } 152 153 /** Extend the timeout for this Package to be verified. */ extendTimeout()154 void extendTimeout() { 155 if (!mExtendedTimeout) { 156 mExtendedTimeout = true; 157 } 158 } 159 160 /** 161 * Returns whether the timeout was extended for verification. 162 * 163 * @return {@code true} if a timeout was already extended. 164 */ timeoutExtended()165 boolean timeoutExtended() { 166 return mExtendedTimeout; 167 } 168 setIntegrityVerificationResult(int code)169 void setIntegrityVerificationResult(int code) { 170 mIntegrityVerificationComplete = true; 171 } 172 isIntegrityVerificationComplete()173 boolean isIntegrityVerificationComplete() { 174 return mIntegrityVerificationComplete; 175 } 176 areAllVerificationsComplete()177 boolean areAllVerificationsComplete() { 178 return mIntegrityVerificationComplete && isVerificationComplete(); 179 } 180 } 181