1 /*
2  * Copyright (C) 2021 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.security.attestationverification;
18 
19 import android.annotation.NonNull;
20 import android.os.Binder;
21 import android.os.Bundle;
22 import android.os.Parcelable;
23 import android.security.attestationverification.AttestationVerificationManager.LocalBindingType;
24 import android.security.attestationverification.AttestationVerificationManager.VerificationResult;
25 
26 import com.android.internal.util.DataClass;
27 import com.android.internal.util.Parcelling;
28 import com.android.internal.util.Parcelling.BuiltIn.ForInstant;
29 
30 import java.time.Duration;
31 import java.util.concurrent.Executor;
32 import java.util.function.BiConsumer;
33 
34 /**
35  * Token representing the result of an attestation verification, which can be passed to other parts
36  * of the OS or other apps as proof of the verification.
37  *
38  * Tokens are only valid within the same UID (which means within a single app unless the deprecated
39  * android:sharedUserId manifest value is used).
40  *
41  * @hide
42  * @see Bundle#putParcelable(String, Parcelable)
43  */
44 @DataClass(
45         genConstructor = false,
46         genHiddenBuilder = true
47 )
48 public final class VerificationToken implements Parcelable {
49 
50     /**
51      * The attestation profile which was used to perform the verification.
52      * @hide
53      */
54     @NonNull
55     private final AttestationProfile mAttestationProfile;
56 
57     /**
58      * The local binding type of the local binding data used to perform the verification.
59      * @hide
60      */
61     @LocalBindingType
62     private final int mLocalBindingType;
63 
64     /**
65      * The requirements used to perform the verification.
66      * @hide
67      */
68     @NonNull
69     private final Bundle mRequirements;
70 
71     /**
72      * The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
73      * byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
74      * accidentally reading this value without calling {@code verifyToken}. Do <b>not</b> use this
75      * value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
76      * Duration)} to verify a valid token and it will return this value.
77      *
78      * If the token is valid, this value is returned directly by {#verifyToken}.
79      *
80      * @hide
81      */
82     @VerificationResult
83     private final int mVerificationResult;
84 
85     /**
86      * Time when the token was generated, set by the system.
87      */
88     @NonNull
89     @DataClass.ParcelWith(ForInstant.class)
90     private final java.time.Instant mVerificationTime;
91 
92     /**
93      * A Hash-based message authentication code used to verify the contents and authenticity of the
94      * rest of the token. The hash is created using a secret key known only to the system server.
95      * When verifying the token, the system re-hashes the token and verifies the generated HMAC is
96      * the same.
97      *
98      * @hide
99      */
100     @NonNull
101     private final byte[] mHmac;
102 
103     /**
104      * The UID of the process which called {@code verifyAttestation} to create the token, as
105      * returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
106      * of calling process does not match this value. This ensures that tokens cannot be shared
107      * between UIDs.
108      *
109      * @hide
110      */
111     private int mUid;
112 
113 
114     // Code below generated by codegen v1.0.23.
115     //
116     // DO NOT MODIFY!
117     // CHECKSTYLE:OFF Generated code
118     //
119     // To regenerate run:
120     // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/security/attestationverification/VerificationToken.java
121     //
122     // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
123     //   Settings > Editor > Code Style > Formatter Control
124     //@formatter:off
125 
126 
127     @DataClass.Generated.Member
VerificationToken( @onNull AttestationProfile attestationProfile, @LocalBindingType int localBindingType, @NonNull Bundle requirements, @VerificationResult int verificationResult, @NonNull java.time.Instant verificationTime, @NonNull byte[] hmac, int uid)128     /* package-private */ VerificationToken(
129             @NonNull AttestationProfile attestationProfile,
130             @LocalBindingType int localBindingType,
131             @NonNull Bundle requirements,
132             @VerificationResult int verificationResult,
133             @NonNull java.time.Instant verificationTime,
134             @NonNull byte[] hmac,
135             int uid) {
136         this.mAttestationProfile = attestationProfile;
137         com.android.internal.util.AnnotationValidations.validate(
138                 NonNull.class, null, mAttestationProfile);
139         this.mLocalBindingType = localBindingType;
140         com.android.internal.util.AnnotationValidations.validate(
141                 LocalBindingType.class, null, mLocalBindingType);
142         this.mRequirements = requirements;
143         com.android.internal.util.AnnotationValidations.validate(
144                 NonNull.class, null, mRequirements);
145         this.mVerificationResult = verificationResult;
146         com.android.internal.util.AnnotationValidations.validate(
147                 VerificationResult.class, null, mVerificationResult);
148         this.mVerificationTime = verificationTime;
149         com.android.internal.util.AnnotationValidations.validate(
150                 NonNull.class, null, mVerificationTime);
151         this.mHmac = hmac;
152         com.android.internal.util.AnnotationValidations.validate(
153                 NonNull.class, null, mHmac);
154         this.mUid = uid;
155 
156         // onConstructed(); // You can define this method to get a callback
157     }
158 
159     /**
160      * The attestation profile which was used to perform the verification.
161      */
162     @DataClass.Generated.Member
getAttestationProfile()163     public @NonNull AttestationProfile getAttestationProfile() {
164         return mAttestationProfile;
165     }
166 
167     /**
168      * The local binding type of the local binding data used to perform the verification.
169      */
170     @DataClass.Generated.Member
getLocalBindingType()171     public @LocalBindingType int getLocalBindingType() {
172         return mLocalBindingType;
173     }
174 
175     /**
176      * The requirements used to perform the verification.
177      */
178     @DataClass.Generated.Member
getRequirements()179     public @NonNull Bundle getRequirements() {
180         return mRequirements;
181     }
182 
183     /**
184      * The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
185      * byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
186      * accidentally reading this value without calling {@code verifyToken}. Do <b>not</b> use this
187      * value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
188      * Duration)} to verify a valid token and it will return this value.
189      *
190      * If the token is valid, this value is returned directly by {#verifyToken}.
191      *
192      * @hide
193      */
194     @DataClass.Generated.Member
getVerificationResult()195     public @VerificationResult int getVerificationResult() {
196         return mVerificationResult;
197     }
198 
199     /**
200      * Time when the token was generated, set by the system.
201      */
202     @DataClass.Generated.Member
getVerificationTime()203     public @NonNull java.time.Instant getVerificationTime() {
204         return mVerificationTime;
205     }
206 
207     /**
208      * A Hash-based message authentication code used to verify the contents and authenticity of the
209      * rest of the token. The hash is created using a secret key known only to the system server.
210      * When verifying the token, the system re-hashes the token and verifies the generated HMAC is
211      * the same.
212      *
213      * @hide
214      */
215     @DataClass.Generated.Member
getHmac()216     public @NonNull byte[] getHmac() {
217         return mHmac;
218     }
219 
220     /**
221      * The UID of the process which called {@code verifyAttestation} to create the token, as
222      * returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
223      * of calling process does not match this value. This ensures that tokens cannot be shared
224      * between UIDs.
225      *
226      * @hide
227      */
228     @DataClass.Generated.Member
getUid()229     public int getUid() {
230         return mUid;
231     }
232 
233     @DataClass.Generated.Member
234     static Parcelling<java.time.Instant> sParcellingForVerificationTime =
235             Parcelling.Cache.get(
236                     ForInstant.class);
237     static {
238         if (sParcellingForVerificationTime == null) {
239             sParcellingForVerificationTime = Parcelling.Cache.put(
240                     new ForInstant());
241         }
242     }
243 
244     @Override
245     @DataClass.Generated.Member
writeToParcel(@onNull android.os.Parcel dest, int flags)246     public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
247         // You can override field parcelling by defining methods like:
248         // void parcelFieldName(Parcel dest, int flags) { ... }
249 
250         dest.writeTypedObject(mAttestationProfile, flags);
251         dest.writeInt(mLocalBindingType);
252         dest.writeBundle(mRequirements);
253         dest.writeInt(mVerificationResult);
254         sParcellingForVerificationTime.parcel(mVerificationTime, dest, flags);
255         dest.writeByteArray(mHmac);
256         dest.writeInt(mUid);
257     }
258 
259     @Override
260     @DataClass.Generated.Member
describeContents()261     public int describeContents() { return 0; }
262 
263     /** @hide */
264     @SuppressWarnings({"unchecked", "RedundantCast"})
265     @DataClass.Generated.Member
VerificationToken(@onNull android.os.Parcel in)266     /* package-private */ VerificationToken(@NonNull android.os.Parcel in) {
267         // You can override field unparcelling by defining methods like:
268         // static FieldType unparcelFieldName(Parcel in) { ... }
269 
270         AttestationProfile attestationProfile = (AttestationProfile) in.readTypedObject(AttestationProfile.CREATOR);
271         int localBindingType = in.readInt();
272         Bundle requirements = in.readBundle();
273         int verificationResult = in.readInt();
274         java.time.Instant verificationTime = sParcellingForVerificationTime.unparcel(in);
275         byte[] hmac = in.createByteArray();
276         int uid = in.readInt();
277 
278         this.mAttestationProfile = attestationProfile;
279         com.android.internal.util.AnnotationValidations.validate(
280                 NonNull.class, null, mAttestationProfile);
281         this.mLocalBindingType = localBindingType;
282         com.android.internal.util.AnnotationValidations.validate(
283                 LocalBindingType.class, null, mLocalBindingType);
284         this.mRequirements = requirements;
285         com.android.internal.util.AnnotationValidations.validate(
286                 NonNull.class, null, mRequirements);
287         this.mVerificationResult = verificationResult;
288         com.android.internal.util.AnnotationValidations.validate(
289                 VerificationResult.class, null, mVerificationResult);
290         this.mVerificationTime = verificationTime;
291         com.android.internal.util.AnnotationValidations.validate(
292                 NonNull.class, null, mVerificationTime);
293         this.mHmac = hmac;
294         com.android.internal.util.AnnotationValidations.validate(
295                 NonNull.class, null, mHmac);
296         this.mUid = uid;
297 
298         // onConstructed(); // You can define this method to get a callback
299     }
300 
301     @DataClass.Generated.Member
302     public static final @NonNull Parcelable.Creator<VerificationToken> CREATOR
303             = new Parcelable.Creator<VerificationToken>() {
304         @Override
305         public VerificationToken[] newArray(int size) {
306             return new VerificationToken[size];
307         }
308 
309         @Override
310         public VerificationToken createFromParcel(@NonNull android.os.Parcel in) {
311             return new VerificationToken(in);
312         }
313     };
314 
315     /**
316      * A builder for {@link VerificationToken}
317      * @hide
318      */
319     @SuppressWarnings("WeakerAccess")
320     @DataClass.Generated.Member
321     public static final class Builder {
322 
323         private @NonNull AttestationProfile mAttestationProfile;
324         private @LocalBindingType int mLocalBindingType;
325         private @NonNull Bundle mRequirements;
326         private @VerificationResult int mVerificationResult;
327         private @NonNull java.time.Instant mVerificationTime;
328         private @NonNull byte[] mHmac;
329         private int mUid;
330 
331         private long mBuilderFieldsSet = 0L;
332 
333         /**
334          * Creates a new Builder.
335          *
336          * @param attestationProfile
337          *   The attestation profile which was used to perform the verification.
338          * @param localBindingType
339          *   The local binding type of the local binding data used to perform the verification.
340          * @param requirements
341          *   The requirements used to perform the verification.
342          * @param verificationResult
343          *   The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
344          *   byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
345          *   accidentally reading this value without calling {@code verifyToken}. Do <b>not</b> use this
346          *   value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
347          *   Duration)} to verify a valid token and it will return this value.
348          *
349          *   If the token is valid, this value is returned directly by {#verifyToken}.
350          * @param verificationTime
351          *   Time when the token was generated, set by the system.
352          * @param hmac
353          *   A Hash-based message authentication code used to verify the contents and authenticity of the
354          *   rest of the token. The hash is created using a secret key known only to the system server.
355          *   When verifying the token, the system re-hashes the token and verifies the generated HMAC is
356          *   the same.
357          * @param uid
358          *   The UID of the process which called {@code verifyAttestation} to create the token, as
359          *   returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
360          *   of calling process does not match this value. This ensures that tokens cannot be shared
361          *   between UIDs.
362          */
Builder( @onNull AttestationProfile attestationProfile, @LocalBindingType int localBindingType, @NonNull Bundle requirements, @VerificationResult int verificationResult, @NonNull java.time.Instant verificationTime, @NonNull byte[] hmac, int uid)363         public Builder(
364                 @NonNull AttestationProfile attestationProfile,
365                 @LocalBindingType int localBindingType,
366                 @NonNull Bundle requirements,
367                 @VerificationResult int verificationResult,
368                 @NonNull java.time.Instant verificationTime,
369                 @NonNull byte[] hmac,
370                 int uid) {
371             mAttestationProfile = attestationProfile;
372             com.android.internal.util.AnnotationValidations.validate(
373                     NonNull.class, null, mAttestationProfile);
374             mLocalBindingType = localBindingType;
375             com.android.internal.util.AnnotationValidations.validate(
376                     LocalBindingType.class, null, mLocalBindingType);
377             mRequirements = requirements;
378             com.android.internal.util.AnnotationValidations.validate(
379                     NonNull.class, null, mRequirements);
380             mVerificationResult = verificationResult;
381             com.android.internal.util.AnnotationValidations.validate(
382                     VerificationResult.class, null, mVerificationResult);
383             mVerificationTime = verificationTime;
384             com.android.internal.util.AnnotationValidations.validate(
385                     NonNull.class, null, mVerificationTime);
386             mHmac = hmac;
387             com.android.internal.util.AnnotationValidations.validate(
388                     NonNull.class, null, mHmac);
389             mUid = uid;
390         }
391 
392         /**
393          * The attestation profile which was used to perform the verification.
394          */
395         @DataClass.Generated.Member
setAttestationProfile(@onNull AttestationProfile value)396         public @NonNull Builder setAttestationProfile(@NonNull AttestationProfile value) {
397             checkNotUsed();
398             mBuilderFieldsSet |= 0x1;
399             mAttestationProfile = value;
400             return this;
401         }
402 
403         /**
404          * The local binding type of the local binding data used to perform the verification.
405          */
406         @DataClass.Generated.Member
setLocalBindingType(@ocalBindingType int value)407         public @NonNull Builder setLocalBindingType(@LocalBindingType int value) {
408             checkNotUsed();
409             mBuilderFieldsSet |= 0x2;
410             mLocalBindingType = value;
411             return this;
412         }
413 
414         /**
415          * The requirements used to perform the verification.
416          */
417         @DataClass.Generated.Member
setRequirements(@onNull Bundle value)418         public @NonNull Builder setRequirements(@NonNull Bundle value) {
419             checkNotUsed();
420             mBuilderFieldsSet |= 0x4;
421             mRequirements = value;
422             return this;
423         }
424 
425         /**
426          * The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
427          * byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
428          * accidentally reading this value without calling {@code verifyToken}. Do <b>not</b> use this
429          * value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
430          * Duration)} to verify a valid token and it will return this value.
431          *
432          * If the token is valid, this value is returned directly by {#verifyToken}.
433          *
434          * @hide
435          */
436         @DataClass.Generated.Member
setVerificationResult(@erificationResult int value)437         public @NonNull Builder setVerificationResult(@VerificationResult int value) {
438             checkNotUsed();
439             mBuilderFieldsSet |= 0x8;
440             mVerificationResult = value;
441             return this;
442         }
443 
444         /**
445          * Time when the token was generated, set by the system.
446          */
447         @DataClass.Generated.Member
setVerificationTime(@onNull java.time.Instant value)448         public @NonNull Builder setVerificationTime(@NonNull java.time.Instant value) {
449             checkNotUsed();
450             mBuilderFieldsSet |= 0x10;
451             mVerificationTime = value;
452             return this;
453         }
454 
455         /**
456          * A Hash-based message authentication code used to verify the contents and authenticity of the
457          * rest of the token. The hash is created using a secret key known only to the system server.
458          * When verifying the token, the system re-hashes the token and verifies the generated HMAC is
459          * the same.
460          *
461          * @hide
462          */
463         @DataClass.Generated.Member
setHmac(@onNull byte... value)464         public @NonNull Builder setHmac(@NonNull byte... value) {
465             checkNotUsed();
466             mBuilderFieldsSet |= 0x20;
467             mHmac = value;
468             return this;
469         }
470 
471         /**
472          * The UID of the process which called {@code verifyAttestation} to create the token, as
473          * returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
474          * of calling process does not match this value. This ensures that tokens cannot be shared
475          * between UIDs.
476          *
477          * @hide
478          */
479         @DataClass.Generated.Member
setUid(int value)480         public @NonNull Builder setUid(int value) {
481             checkNotUsed();
482             mBuilderFieldsSet |= 0x40;
483             mUid = value;
484             return this;
485         }
486 
487         /** Builds the instance. This builder should not be touched after calling this! */
build()488         public @NonNull VerificationToken build() {
489             checkNotUsed();
490             mBuilderFieldsSet |= 0x80; // Mark builder used
491 
492             VerificationToken o = new VerificationToken(
493                     mAttestationProfile,
494                     mLocalBindingType,
495                     mRequirements,
496                     mVerificationResult,
497                     mVerificationTime,
498                     mHmac,
499                     mUid);
500             return o;
501         }
502 
checkNotUsed()503         private void checkNotUsed() {
504             if ((mBuilderFieldsSet & 0x80) != 0) {
505                 throw new IllegalStateException(
506                         "This Builder should not be reused. Use a new Builder instance instead");
507             }
508         }
509     }
510 
511     @DataClass.Generated(
512             time = 1633629747234L,
513             codegenVersion = "1.0.23",
514             sourceFile = "frameworks/base/core/java/android/security/attestationverification/VerificationToken.java",
515             inputSignatures = "private final @android.annotation.NonNull android.security.attestationverification.AttestationProfile mAttestationProfile\nprivate final @android.security.attestationverification.AttestationVerificationManager.LocalBindingType int mLocalBindingType\nprivate final @android.annotation.NonNull android.os.Bundle mRequirements\nprivate final  @android.security.attestationverification.AttestationVerificationManager.VerificationResult int mVerificationResult\nprivate final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInstant.class) java.time.Instant mVerificationTime\nprivate final @android.annotation.NonNull byte[] mHmac\nprivate  int mUid\nclass VerificationToken extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genHiddenBuilder=true)")
516     @Deprecated
__metadata()517     private void __metadata() {}
518 
519 
520     //@formatter:on
521     // End of generated code
522 
523 }
524