• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 android.content.integrity;
18 
19 import android.annotation.NonNull;
20 
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Objects;
25 
26 /**
27  * The app install metadata.
28  *
29  * <p>The integrity component retrieves metadata for app installs from package manager, passing it
30  * to the rule evaluation engine to evaluate the metadata against the rules.
31  *
32  * <p>Instances of this class are immutable.
33  *
34  * @hide
35  */
36 public final class AppInstallMetadata {
37     private final String mPackageName;
38     // Raw string encoding for the SHA-256 hash of the certificate of the app.
39     private final List<String> mAppCertificates;
40     private final String mInstallerName;
41     // Raw string encoding for the SHA-256 hash of the certificate of the installer.
42     private final List<String> mInstallerCertificates;
43     private final long mVersionCode;
44     private final boolean mIsPreInstalled;
45     private final boolean mIsStampPresent;
46     private final boolean mIsStampVerified;
47     private final boolean mIsStampTrusted;
48     // Raw string encoding for the SHA-256 hash of the certificate of the stamp.
49     private final String mStampCertificateHash;
50     private final Map<String, String> mAllowedInstallersAndCertificates;
51 
AppInstallMetadata(Builder builder)52     private AppInstallMetadata(Builder builder) {
53         this.mPackageName = builder.mPackageName;
54         this.mAppCertificates = builder.mAppCertificates;
55         this.mInstallerName = builder.mInstallerName;
56         this.mInstallerCertificates = builder.mInstallerCertificates;
57         this.mVersionCode = builder.mVersionCode;
58         this.mIsPreInstalled = builder.mIsPreInstalled;
59         this.mIsStampPresent = builder.mIsStampPresent;
60         this.mIsStampVerified = builder.mIsStampVerified;
61         this.mIsStampTrusted = builder.mIsStampTrusted;
62         this.mStampCertificateHash = builder.mStampCertificateHash;
63         this.mAllowedInstallersAndCertificates = builder.mAllowedInstallersAndCertificates;
64     }
65 
66     @NonNull
getPackageName()67     public String getPackageName() {
68         return mPackageName;
69     }
70 
71     @NonNull
getAppCertificates()72     public List<String> getAppCertificates() {
73         return mAppCertificates;
74     }
75 
76     @NonNull
getInstallerName()77     public String getInstallerName() {
78         return mInstallerName;
79     }
80 
81     @NonNull
getInstallerCertificates()82     public List<String> getInstallerCertificates() {
83         return mInstallerCertificates;
84     }
85 
86     /** @see AppInstallMetadata.Builder#setVersionCode(long) */
getVersionCode()87     public long getVersionCode() {
88         return mVersionCode;
89     }
90 
91     /** @see AppInstallMetadata.Builder#setIsPreInstalled(boolean) */
isPreInstalled()92     public boolean isPreInstalled() {
93         return mIsPreInstalled;
94     }
95 
96     /** @see AppInstallMetadata.Builder#setIsStampPresent(boolean) */
isStampPresent()97     public boolean isStampPresent() {
98         return mIsStampPresent;
99     }
100 
101     /** @see AppInstallMetadata.Builder#setIsStampVerified(boolean) */
isStampVerified()102     public boolean isStampVerified() {
103         return mIsStampVerified;
104     }
105 
106     /** @see AppInstallMetadata.Builder#setIsStampTrusted(boolean) */
isStampTrusted()107     public boolean isStampTrusted() {
108         return mIsStampTrusted;
109     }
110 
111     /** @see AppInstallMetadata.Builder#setStampCertificateHash(String) */
getStampCertificateHash()112     public String getStampCertificateHash() {
113         return mStampCertificateHash;
114     }
115 
116     /** Get the allowed installers and their corresponding cert. */
getAllowedInstallersAndCertificates()117     public Map<String, String> getAllowedInstallersAndCertificates() {
118         return mAllowedInstallersAndCertificates;
119     }
120 
121     @Override
toString()122     public String toString() {
123         return String.format(
124                 "AppInstallMetadata { PackageName = %s, AppCerts = %s, InstallerName = %s,"
125                     + " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b, StampPresent ="
126                     + " %b, StampVerified = %b, StampTrusted = %b, StampCert = %s }",
127                 mPackageName,
128                 mAppCertificates,
129                 mInstallerName == null ? "null" : mInstallerName,
130                 mInstallerCertificates == null ? "null" : mInstallerCertificates,
131                 mVersionCode,
132                 mIsPreInstalled,
133                 mIsStampPresent,
134                 mIsStampVerified,
135                 mIsStampTrusted,
136                 mStampCertificateHash == null ? "null" : mStampCertificateHash);
137     }
138 
139     /** Builder class for constructing {@link AppInstallMetadata} objects. */
140     public static final class Builder {
141         private String mPackageName;
142         private List<String> mAppCertificates;
143         private String mInstallerName;
144         private List<String> mInstallerCertificates;
145         private long mVersionCode;
146         private boolean mIsPreInstalled;
147         private boolean mIsStampPresent;
148         private boolean mIsStampVerified;
149         private boolean mIsStampTrusted;
150         private String mStampCertificateHash;
151         private Map<String, String> mAllowedInstallersAndCertificates;
152 
Builder()153         public Builder() {
154             mAllowedInstallersAndCertificates = new HashMap<>();
155         }
156 
157         /**
158          * Add allowed installers and cert.
159          *
160          * @see AppInstallMetadata#getAllowedInstallersAndCertificates()
161          */
162         @NonNull
setAllowedInstallersAndCert( @onNull Map<String, String> allowedInstallersAndCertificates)163         public Builder setAllowedInstallersAndCert(
164                 @NonNull Map<String, String> allowedInstallersAndCertificates) {
165             this.mAllowedInstallersAndCertificates = allowedInstallersAndCertificates;
166             return this;
167         }
168 
169         /**
170          * Set package name of the app to be installed.
171          *
172          * @see AppInstallMetadata#getPackageName()
173          */
174         @NonNull
setPackageName(@onNull String packageName)175         public Builder setPackageName(@NonNull String packageName) {
176             this.mPackageName = Objects.requireNonNull(packageName);
177             return this;
178         }
179 
180         /**
181          * Set certificate of the app to be installed.
182          *
183          * <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
184          * of the app.
185          *
186          * @see AppInstallMetadata#getAppCertificates()
187          */
188         @NonNull
setAppCertificates(@onNull List<String> appCertificates)189         public Builder setAppCertificates(@NonNull List<String> appCertificates) {
190             this.mAppCertificates = Objects.requireNonNull(appCertificates);
191             return this;
192         }
193 
194         /**
195          * Set name of the installer installing the app.
196          *
197          * @see AppInstallMetadata#getInstallerName()
198          */
199         @NonNull
setInstallerName(@onNull String installerName)200         public Builder setInstallerName(@NonNull String installerName) {
201             this.mInstallerName = Objects.requireNonNull(installerName);
202             return this;
203         }
204 
205         /**
206          * Set certificate of the installer installing the app.
207          *
208          * <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
209          * of the installer.
210          *
211          * @see AppInstallMetadata#getInstallerCertificates()
212          */
213         @NonNull
setInstallerCertificates(@onNull List<String> installerCertificates)214         public Builder setInstallerCertificates(@NonNull List<String> installerCertificates) {
215             this.mInstallerCertificates = Objects.requireNonNull(installerCertificates);
216             return this;
217         }
218 
219         /**
220          * Set version code of the app to be installed.
221          *
222          * @see AppInstallMetadata#getVersionCode()
223          */
224         @NonNull
setVersionCode(long versionCode)225         public Builder setVersionCode(long versionCode) {
226             this.mVersionCode = versionCode;
227             return this;
228         }
229 
230         /**
231          * Set whether the app is pre-installed on the device or not.
232          *
233          * @see AppInstallMetadata#isPreInstalled()
234          */
235         @NonNull
setIsPreInstalled(boolean isPreInstalled)236         public Builder setIsPreInstalled(boolean isPreInstalled) {
237             this.mIsPreInstalled = isPreInstalled;
238             return this;
239         }
240 
241         /**
242          * Set whether the stamp embedded in the APK is present or not.
243          *
244          * @see AppInstallMetadata#isStampPresent()
245          */
246         @NonNull
setIsStampPresent(boolean isStampPresent)247         public Builder setIsStampPresent(boolean isStampPresent) {
248             this.mIsStampPresent = isStampPresent;
249             return this;
250         }
251 
252         /**
253          * Set whether the stamp embedded in the APK is verified or not.
254          *
255          * @see AppInstallMetadata#isStampVerified()
256          */
257         @NonNull
setIsStampVerified(boolean isStampVerified)258         public Builder setIsStampVerified(boolean isStampVerified) {
259             this.mIsStampVerified = isStampVerified;
260             return this;
261         }
262 
263         /**
264          * Set whether the stamp embedded in the APK is trusted or not.
265          *
266          * @see AppInstallMetadata#isStampTrusted()
267          */
268         @NonNull
setIsStampTrusted(boolean isStampTrusted)269         public Builder setIsStampTrusted(boolean isStampTrusted) {
270             this.mIsStampTrusted = isStampTrusted;
271             return this;
272         }
273 
274         /**
275          * Set certificate hash of the stamp embedded in the APK.
276          *
277          * <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
278          * of the stamp.
279          *
280          * @see AppInstallMetadata#getStampCertificateHash()
281          */
282         @NonNull
setStampCertificateHash(@onNull String stampCertificateHash)283         public Builder setStampCertificateHash(@NonNull String stampCertificateHash) {
284             this.mStampCertificateHash = Objects.requireNonNull(stampCertificateHash);
285             return this;
286         }
287 
288         /**
289          * Build {@link AppInstallMetadata}.
290          *
291          * @throws IllegalArgumentException if package name or app certificate is null
292          */
293         @NonNull
build()294         public AppInstallMetadata build() {
295             Objects.requireNonNull(mPackageName);
296             Objects.requireNonNull(mAppCertificates);
297             return new AppInstallMetadata(this);
298         }
299     }
300 }
301