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 /** 23 * Tracks the package verification state for a particular package. Each package verification has a 24 * required verifier and zero or more sufficient verifiers. Only one of the sufficient verifier list 25 * must return affirmative to allow the package to be considered verified. If there are zero 26 * sufficient verifiers, then package verification is considered complete. 27 */ 28 class PackageVerificationState { 29 private final VerificationParams mParams; 30 31 private final SparseBooleanArray mSufficientVerifierUids; 32 33 private int mRequiredVerifierUid; 34 35 private boolean mSufficientVerificationComplete; 36 37 private boolean mSufficientVerificationPassed; 38 39 private boolean mRequiredVerificationComplete; 40 41 private boolean mRequiredVerificationPassed; 42 43 private boolean mExtendedTimeout; 44 45 private boolean mIntegrityVerificationComplete; 46 47 /** 48 * Create a new package verification state where {@code requiredVerifierUid} is the user ID for 49 * the package that must reply affirmative before things can continue. 50 */ PackageVerificationState(VerificationParams params)51 PackageVerificationState(VerificationParams params) { 52 mParams = params; 53 mSufficientVerifierUids = new SparseBooleanArray(); 54 mExtendedTimeout = false; 55 } 56 getVerificationParams()57 VerificationParams getVerificationParams() { 58 return mParams; 59 } 60 61 /** Sets the user ID of the required package verifier. */ setRequiredVerifierUid(int uid)62 void setRequiredVerifierUid(int uid) { 63 mRequiredVerifierUid = uid; 64 } 65 66 /** 67 * Add a verifier which is added to our sufficient list. 68 * 69 * @param uid user ID of sufficient verifier 70 */ addSufficientVerifier(int uid)71 void addSufficientVerifier(int uid) { 72 mSufficientVerifierUids.put(uid, true); 73 } 74 75 /** 76 * Should be called when a verification is received from an agent so the state of the package 77 * verification can be tracked. 78 * 79 * @param uid user ID of the verifying agent 80 * @return {@code true} if the verifying agent actually exists in our list 81 */ setVerifierResponse(int uid, int code)82 boolean setVerifierResponse(int uid, int code) { 83 if (uid == mRequiredVerifierUid) { 84 mRequiredVerificationComplete = true; 85 switch (code) { 86 case PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT: 87 mSufficientVerifierUids.clear(); 88 // fall through 89 case PackageManager.VERIFICATION_ALLOW: 90 mRequiredVerificationPassed = true; 91 break; 92 default: 93 mRequiredVerificationPassed = false; 94 } 95 return true; 96 } else { 97 if (mSufficientVerifierUids.get(uid)) { 98 if (code == PackageManager.VERIFICATION_ALLOW) { 99 mSufficientVerificationComplete = true; 100 mSufficientVerificationPassed = true; 101 } 102 103 mSufficientVerifierUids.delete(uid); 104 if (mSufficientVerifierUids.size() == 0) { 105 mSufficientVerificationComplete = true; 106 } 107 108 return true; 109 } 110 } 111 112 return false; 113 } 114 115 /** 116 * Returns whether verification is considered complete. This means that the required verifier 117 * and at least one of the sufficient verifiers has returned a positive verification. 118 * 119 * @return {@code true} when verification is considered complete 120 */ isVerificationComplete()121 boolean isVerificationComplete() { 122 if (!mRequiredVerificationComplete) { 123 return false; 124 } 125 126 if (mSufficientVerifierUids.size() == 0) { 127 return true; 128 } 129 130 return mSufficientVerificationComplete; 131 } 132 133 /** 134 * Returns whether installation should be allowed. This should only be called after {@link 135 * #isVerificationComplete()} returns {@code true}. 136 * 137 * @return {@code true} if installation should be allowed 138 */ isInstallAllowed()139 boolean isInstallAllowed() { 140 if (!mRequiredVerificationPassed) { 141 return false; 142 } 143 144 if (mSufficientVerificationComplete) { 145 return mSufficientVerificationPassed; 146 } 147 148 return true; 149 } 150 151 /** Extend the timeout for this Package to be verified. */ extendTimeout()152 void extendTimeout() { 153 if (!mExtendedTimeout) { 154 mExtendedTimeout = true; 155 } 156 } 157 158 /** 159 * Returns whether the timeout was extended for verification. 160 * 161 * @return {@code true} if a timeout was already extended. 162 */ timeoutExtended()163 boolean timeoutExtended() { 164 return mExtendedTimeout; 165 } 166 setIntegrityVerificationResult(int code)167 void setIntegrityVerificationResult(int code) { 168 mIntegrityVerificationComplete = true; 169 } 170 isIntegrityVerificationComplete()171 boolean isIntegrityVerificationComplete() { 172 return mIntegrityVerificationComplete; 173 } 174 areAllVerificationsComplete()175 boolean areAllVerificationsComplete() { 176 return mIntegrityVerificationComplete && isVerificationComplete(); 177 } 178 } 179