• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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