• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019, The Android Open Source Project, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *   http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package com.google.android.attestation;
17 
18 import static com.google.android.attestation.AuthorizationList.UserAuthType.FINGERPRINT;
19 import static com.google.android.attestation.AuthorizationList.UserAuthType.PASSWORD;
20 import static com.google.android.attestation.AuthorizationList.UserAuthType.USER_AUTH_TYPE_ANY;
21 import static com.google.android.attestation.AuthorizationList.UserAuthType.USER_AUTH_TYPE_NONE;
22 import static com.google.android.attestation.Constants.KM_TAG_ACTIVE_DATE_TIME;
23 import static com.google.android.attestation.Constants.KM_TAG_ALGORITHM;
24 import static com.google.android.attestation.Constants.KM_TAG_ALLOW_WHILE_ON_BODY;
25 import static com.google.android.attestation.Constants.KM_TAG_ALL_APPLICATIONS;
26 import static com.google.android.attestation.Constants.KM_TAG_APPLICATION_ID;
27 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_APPLICATION_ID;
28 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_ID_BRAND;
29 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_ID_DEVICE;
30 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_ID_IMEI;
31 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_ID_MANUFACTURER;
32 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_ID_MEID;
33 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_ID_MODEL;
34 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_ID_PRODUCT;
35 import static com.google.android.attestation.Constants.KM_TAG_ATTESTATION_ID_SERIAL;
36 import static com.google.android.attestation.Constants.KM_TAG_AUTH_TIMEOUT;
37 import static com.google.android.attestation.Constants.KM_TAG_BOOT_PATCH_LEVEL;
38 import static com.google.android.attestation.Constants.KM_TAG_CREATION_DATE_TIME;
39 import static com.google.android.attestation.Constants.KM_TAG_DEVICE_UNIQUE_ATTESTATION;
40 import static com.google.android.attestation.Constants.KM_TAG_DIGEST;
41 import static com.google.android.attestation.Constants.KM_TAG_EC_CURVE;
42 import static com.google.android.attestation.Constants.KM_TAG_KEY_SIZE;
43 import static com.google.android.attestation.Constants.KM_TAG_NO_AUTH_REQUIRED;
44 import static com.google.android.attestation.Constants.KM_TAG_ORIGIN;
45 import static com.google.android.attestation.Constants.KM_TAG_ORIGINATION_EXPIRE_DATE_TIME;
46 import static com.google.android.attestation.Constants.KM_TAG_OS_PATCH_LEVEL;
47 import static com.google.android.attestation.Constants.KM_TAG_OS_VERSION;
48 import static com.google.android.attestation.Constants.KM_TAG_PADDING;
49 import static com.google.android.attestation.Constants.KM_TAG_PURPOSE;
50 import static com.google.android.attestation.Constants.KM_TAG_ROLLBACK_RESISTANCE;
51 import static com.google.android.attestation.Constants.KM_TAG_ROLLBACK_RESISTANT;
52 import static com.google.android.attestation.Constants.KM_TAG_ROOT_OF_TRUST;
53 import static com.google.android.attestation.Constants.KM_TAG_RSA_PUBLIC_EXPONENT;
54 import static com.google.android.attestation.Constants.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED;
55 import static com.google.android.attestation.Constants.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED;
56 import static com.google.android.attestation.Constants.KM_TAG_UNLOCKED_DEVICE_REQUIRED;
57 import static com.google.android.attestation.Constants.KM_TAG_USAGE_EXPIRE_DATE_TIME;
58 import static com.google.android.attestation.Constants.KM_TAG_USER_AUTH_TYPE;
59 import static com.google.android.attestation.Constants.KM_TAG_VENDOR_PATCH_LEVEL;
60 import static com.google.android.attestation.Constants.UINT32_MAX;
61 
62 import java.time.Duration;
63 import java.time.Instant;
64 import java.util.HashMap;
65 import java.util.HashSet;
66 import java.util.Map;
67 import java.util.Optional;
68 import java.util.Set;
69 import org.bouncycastle.asn1.ASN1Encodable;
70 import org.bouncycastle.asn1.ASN1EncodableVector;
71 import org.bouncycastle.asn1.ASN1Integer;
72 import org.bouncycastle.asn1.ASN1OctetString;
73 import org.bouncycastle.asn1.ASN1Primitive;
74 import org.bouncycastle.asn1.ASN1Sequence;
75 import org.bouncycastle.asn1.ASN1Set;
76 import org.bouncycastle.asn1.ASN1TaggedObject;
77 import org.bouncycastle.asn1.DERNull;
78 import org.bouncycastle.asn1.DEROctetString;
79 import org.bouncycastle.asn1.DERSequence;
80 import org.bouncycastle.asn1.DERSet;
81 import org.bouncycastle.asn1.DERTaggedObject;
82 
83 /**
84  * This data structure contains the key pair's properties themselves, as defined in the Keymaster
85  * hardware abstraction layer (HAL). You compare these values to the device's current state or to a
86  * set of expected values to verify that a key pair is still valid for use in your app.
87  */
88 @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
89 public class AuthorizationList {
90   /** Specifies the types of user authenticators that may be used to authorize this key. */
91   public enum UserAuthType {
92     USER_AUTH_TYPE_NONE,
93     PASSWORD,
94     FINGERPRINT,
95     USER_AUTH_TYPE_ANY
96   }
97 
98   public final Optional<Set<Integer>> purpose;
99   public final Optional<Integer> algorithm;
100   public final Optional<Integer> keySize;
101   public final Optional<Set<Integer>> digest;
102   public final Optional<Set<Integer>> padding;
103   public final Optional<Integer> ecCurve;
104   public final Optional<Long> rsaPublicExponent;
105   public final boolean rollbackResistance;
106   public final Optional<Instant> activeDateTime;
107   public final Optional<Instant> originationExpireDateTime;
108   public final Optional<Instant> usageExpireDateTime;
109   public final boolean noAuthRequired;
110   public final Optional<Set<UserAuthType>> userAuthType;
111   public final Optional<Duration> authTimeout;
112   public final boolean allowWhileOnBody;
113   public final boolean trustedUserPresenceRequired;
114   public final boolean trustedConfirmationRequired;
115   public final boolean unlockedDeviceRequired;
116   public final boolean allApplications;
117   public final Optional<byte[]> applicationId;
118   public final Optional<Instant> creationDateTime;
119   public final Optional<Integer> origin;
120   public final boolean rollbackResistant;
121   public final Optional<RootOfTrust> rootOfTrust;
122   public final Optional<Integer> osVersion;
123   public final Optional<Integer> osPatchLevel;
124   public final Optional<AttestationApplicationId> attestationApplicationId;
125   public final Optional<byte[]> attestationApplicationIdBytes;
126   public final Optional<byte[]> attestationIdBrand;
127   public final Optional<byte[]> attestationIdDevice;
128   public final Optional<byte[]> attestationIdProduct;
129   public final Optional<byte[]> attestationIdSerial;
130   public final Optional<byte[]> attestationIdImei;
131   public final Optional<byte[]> attestationIdMeid;
132   public final Optional<byte[]> attestationIdManufacturer;
133   public final Optional<byte[]> attestationIdModel;
134   public final Optional<Integer> vendorPatchLevel;
135   public final Optional<Integer> bootPatchLevel;
136   public final boolean individualAttestation;
137 
AuthorizationList(ASN1Encodable[] authorizationList, int attestationVersion)138   private AuthorizationList(ASN1Encodable[] authorizationList, int attestationVersion) {
139     Map<Integer, ASN1Primitive> authorizationMap = getAuthorizationMap(authorizationList);
140     this.purpose = findOptionalIntegerSetAuthorizationListEntry(authorizationMap, KM_TAG_PURPOSE);
141     this.algorithm = findOptionalIntegerAuthorizationListEntry(authorizationMap, KM_TAG_ALGORITHM);
142     this.keySize = findOptionalIntegerAuthorizationListEntry(authorizationMap, KM_TAG_KEY_SIZE);
143     this.digest = findOptionalIntegerSetAuthorizationListEntry(authorizationMap, KM_TAG_DIGEST);
144     this.padding = findOptionalIntegerSetAuthorizationListEntry(authorizationMap, KM_TAG_PADDING);
145     this.ecCurve = findOptionalIntegerAuthorizationListEntry(authorizationMap, KM_TAG_EC_CURVE);
146     this.rsaPublicExponent =
147         findOptionalLongAuthorizationListEntry(authorizationMap, KM_TAG_RSA_PUBLIC_EXPONENT);
148     this.rollbackResistance =
149         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_ROLLBACK_RESISTANCE);
150     this.activeDateTime =
151         findOptionalInstantMillisAuthorizationListEntry(authorizationMap, KM_TAG_ACTIVE_DATE_TIME);
152     this.originationExpireDateTime =
153         findOptionalInstantMillisAuthorizationListEntry(
154             authorizationMap, KM_TAG_ORIGINATION_EXPIRE_DATE_TIME);
155     this.usageExpireDateTime =
156         findOptionalInstantMillisAuthorizationListEntry(
157             authorizationMap, KM_TAG_USAGE_EXPIRE_DATE_TIME);
158     this.noAuthRequired =
159         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_NO_AUTH_REQUIRED);
160     this.userAuthType = findOptionalUserAuthType(authorizationMap, KM_TAG_USER_AUTH_TYPE);
161     this.authTimeout =
162         findOptionalDurationSecondsAuthorizationListEntry(authorizationMap, KM_TAG_AUTH_TIMEOUT);
163     this.allowWhileOnBody =
164         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_ALLOW_WHILE_ON_BODY);
165     this.trustedUserPresenceRequired =
166         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
167     this.trustedConfirmationRequired =
168         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
169     this.unlockedDeviceRequired =
170         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_UNLOCKED_DEVICE_REQUIRED);
171     this.allApplications =
172         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_ALL_APPLICATIONS);
173     this.applicationId =
174         findOptionalByteArrayAuthorizationListEntry(authorizationMap, KM_TAG_APPLICATION_ID);
175     this.creationDateTime =
176         findOptionalInstantMillisAuthorizationListEntry(
177             authorizationMap, KM_TAG_CREATION_DATE_TIME);
178     this.origin = findOptionalIntegerAuthorizationListEntry(authorizationMap, KM_TAG_ORIGIN);
179     this.rollbackResistant =
180         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_ROLLBACK_RESISTANT);
181     this.rootOfTrust =
182         Optional.ofNullable(
183             RootOfTrust.createRootOfTrust(
184                 (ASN1Sequence) findAuthorizationListEntry(authorizationMap, KM_TAG_ROOT_OF_TRUST),
185                 attestationVersion));
186     this.osVersion = findOptionalIntegerAuthorizationListEntry(authorizationMap, KM_TAG_OS_VERSION);
187     this.osPatchLevel =
188         findOptionalIntegerAuthorizationListEntry(authorizationMap, KM_TAG_OS_PATCH_LEVEL);
189     this.attestationApplicationId =
190         Optional.ofNullable(
191             AttestationApplicationId.createAttestationApplicationId(
192                 (DEROctetString)
193                     findAuthorizationListEntry(
194                         authorizationMap, KM_TAG_ATTESTATION_APPLICATION_ID)));
195     this.attestationApplicationIdBytes =
196         findOptionalByteArrayAuthorizationListEntry(
197             authorizationMap, KM_TAG_ATTESTATION_APPLICATION_ID);
198     this.attestationIdBrand =
199         findOptionalByteArrayAuthorizationListEntry(authorizationMap, KM_TAG_ATTESTATION_ID_BRAND);
200     this.attestationIdDevice =
201         findOptionalByteArrayAuthorizationListEntry(authorizationMap, KM_TAG_ATTESTATION_ID_DEVICE);
202     this.attestationIdProduct =
203         findOptionalByteArrayAuthorizationListEntry(
204             authorizationMap, KM_TAG_ATTESTATION_ID_PRODUCT);
205     this.attestationIdSerial =
206         findOptionalByteArrayAuthorizationListEntry(authorizationMap, KM_TAG_ATTESTATION_ID_SERIAL);
207     this.attestationIdImei =
208         findOptionalByteArrayAuthorizationListEntry(authorizationMap, KM_TAG_ATTESTATION_ID_IMEI);
209     this.attestationIdMeid =
210         findOptionalByteArrayAuthorizationListEntry(authorizationMap, KM_TAG_ATTESTATION_ID_MEID);
211     this.attestationIdManufacturer =
212         findOptionalByteArrayAuthorizationListEntry(
213             authorizationMap, KM_TAG_ATTESTATION_ID_MANUFACTURER);
214     this.attestationIdModel =
215         findOptionalByteArrayAuthorizationListEntry(authorizationMap, KM_TAG_ATTESTATION_ID_MODEL);
216     this.vendorPatchLevel =
217         findOptionalIntegerAuthorizationListEntry(authorizationMap, KM_TAG_VENDOR_PATCH_LEVEL);
218     this.bootPatchLevel =
219         findOptionalIntegerAuthorizationListEntry(authorizationMap, KM_TAG_BOOT_PATCH_LEVEL);
220     this.individualAttestation =
221         findBooleanAuthorizationListEntry(authorizationMap, KM_TAG_DEVICE_UNIQUE_ATTESTATION);
222   }
223 
AuthorizationList(Builder builder)224   private AuthorizationList(Builder builder) {
225     this.purpose = Optional.ofNullable(builder.purpose);
226     this.algorithm = Optional.ofNullable(builder.algorithm);
227     this.keySize = Optional.ofNullable(builder.keySize);
228     this.digest = Optional.ofNullable(builder.digest);
229     this.padding = Optional.ofNullable(builder.padding);
230     this.ecCurve = Optional.ofNullable(builder.ecCurve);
231     this.rsaPublicExponent = Optional.ofNullable(builder.rsaPublicExponent);
232     this.rollbackResistance = builder.rollbackResistance;
233     this.activeDateTime = Optional.ofNullable(builder.activeDateTime);
234     this.originationExpireDateTime = Optional.ofNullable(builder.originationExpireDateTime);
235     this.usageExpireDateTime = Optional.ofNullable(builder.usageExpireDateTime);
236     this.noAuthRequired = builder.noAuthRequired;
237     this.userAuthType = Optional.ofNullable(builder.userAuthType);
238     this.authTimeout = Optional.ofNullable(builder.authTimeout);
239     this.allowWhileOnBody = builder.allowWhileOnBody;
240     this.trustedUserPresenceRequired = builder.trustedUserPresenceRequired;
241     this.trustedConfirmationRequired = builder.trustedConfirmationRequired;
242     this.unlockedDeviceRequired = builder.unlockedDeviceRequired;
243     this.allApplications = builder.allApplications;
244     this.applicationId = Optional.ofNullable(builder.applicationId);
245     this.creationDateTime = Optional.ofNullable(builder.creationDateTime);
246     this.origin = Optional.ofNullable(builder.origin);
247     this.rollbackResistant = builder.rollbackResistant;
248     this.rootOfTrust = Optional.ofNullable(builder.rootOfTrust);
249     this.osVersion = Optional.ofNullable(builder.osVersion);
250     this.osPatchLevel = Optional.ofNullable(builder.osPatchLevel);
251     this.attestationApplicationId = Optional.ofNullable(builder.attestationApplicationId);
252     this.attestationApplicationIdBytes = Optional.ofNullable(builder.attestationApplicationIdBytes);
253     this.attestationIdBrand = Optional.ofNullable(builder.attestationIdBrand);
254     this.attestationIdDevice = Optional.ofNullable(builder.attestationIdDevice);
255     this.attestationIdProduct = Optional.ofNullable(builder.attestationIdProduct);
256     this.attestationIdSerial = Optional.ofNullable(builder.attestationIdSerial);
257     this.attestationIdImei = Optional.ofNullable(builder.attestationIdImei);
258     this.attestationIdMeid = Optional.ofNullable(builder.attestationIdMeid);
259     this.attestationIdManufacturer = Optional.ofNullable(builder.attestationIdManufacturer);
260     this.attestationIdModel = Optional.ofNullable(builder.attestationIdModel);
261     this.vendorPatchLevel = Optional.ofNullable(builder.vendorPatchLevel);
262     this.bootPatchLevel = Optional.ofNullable(builder.bootPatchLevel);
263     this.individualAttestation = builder.individualAttestation;
264   }
265 
createAuthorizationList( ASN1Encodable[] authorizationList, int attestationVersion)266   static AuthorizationList createAuthorizationList(
267       ASN1Encodable[] authorizationList, int attestationVersion) {
268     return new AuthorizationList(authorizationList, attestationVersion);
269   }
270 
getAuthorizationMap( ASN1Encodable[] authorizationList)271   private static Map<Integer, ASN1Primitive> getAuthorizationMap(
272       ASN1Encodable[] authorizationList) {
273     Map<Integer, ASN1Primitive> authorizationMap = new HashMap<>();
274     for (ASN1Encodable entry : authorizationList) {
275       ASN1TaggedObject taggedEntry = (ASN1TaggedObject) entry;
276       authorizationMap.put(taggedEntry.getTagNo(), taggedEntry.getObject());
277     }
278     return authorizationMap;
279   }
280 
findAuthorizationListEntry( Map<Integer, ASN1Primitive> authorizationMap, int tag)281   private static ASN1Primitive findAuthorizationListEntry(
282       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
283     return authorizationMap.getOrDefault(tag, null);
284   }
285 
findOptionalIntegerSetAuthorizationListEntry( Map<Integer, ASN1Primitive> authorizationMap, int tag)286   private static Optional<Set<Integer>> findOptionalIntegerSetAuthorizationListEntry(
287       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
288     ASN1Set asn1Set = (ASN1Set) findAuthorizationListEntry(authorizationMap, tag);
289     if (asn1Set == null) {
290       return Optional.empty();
291     }
292     Set<Integer> entrySet = new HashSet<>();
293     for (ASN1Encodable value : asn1Set) {
294       entrySet.add(ASN1Parsing.getIntegerFromAsn1(value));
295     }
296     return Optional.of(entrySet);
297   }
298 
findOptionalDurationSecondsAuthorizationListEntry( Map<Integer, ASN1Primitive> authorizationMap, int tag)299   private static Optional<Duration> findOptionalDurationSecondsAuthorizationListEntry(
300       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
301     Optional<Integer> seconds = findOptionalIntegerAuthorizationListEntry(authorizationMap, tag);
302     return seconds.map(Duration::ofSeconds);
303   }
304 
findOptionalIntegerAuthorizationListEntry( Map<Integer, ASN1Primitive> authorizationMap, int tag)305   private static Optional<Integer> findOptionalIntegerAuthorizationListEntry(
306       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
307     ASN1Primitive entry = findAuthorizationListEntry(authorizationMap, tag);
308     return Optional.ofNullable(entry).map(ASN1Parsing::getIntegerFromAsn1);
309   }
310 
findOptionalInstantMillisAuthorizationListEntry( Map<Integer, ASN1Primitive> authorizationMap, int tag)311   private static Optional<Instant> findOptionalInstantMillisAuthorizationListEntry(
312       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
313     Optional<Long> millis = findOptionalLongAuthorizationListEntry(authorizationMap, tag);
314     return millis.map(Instant::ofEpochMilli);
315   }
316 
findOptionalLongAuthorizationListEntry( Map<Integer, ASN1Primitive> authorizationMap, int tag)317   private static Optional<Long> findOptionalLongAuthorizationListEntry(
318       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
319     ASN1Integer longEntry = ((ASN1Integer) findAuthorizationListEntry(authorizationMap, tag));
320     return Optional.ofNullable(longEntry).map(value -> value.getValue().longValue());
321   }
322 
findBooleanAuthorizationListEntry( Map<Integer, ASN1Primitive> authorizationMap, int tag)323   private static boolean findBooleanAuthorizationListEntry(
324       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
325     return null != findAuthorizationListEntry(authorizationMap, tag);
326   }
327 
findOptionalByteArrayAuthorizationListEntry( Map<Integer, ASN1Primitive> authorizationMap, int tag)328   private static Optional<byte[]> findOptionalByteArrayAuthorizationListEntry(
329       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
330     ASN1OctetString entry = (ASN1OctetString) findAuthorizationListEntry(authorizationMap, tag);
331     return Optional.ofNullable(entry).map(ASN1OctetString::getOctets);
332   }
333 
findOptionalUserAuthType( Map<Integer, ASN1Primitive> authorizationMap, int tag)334   private static Optional<Set<UserAuthType>> findOptionalUserAuthType(
335       Map<Integer, ASN1Primitive> authorizationMap, int tag) {
336     Optional<Long> userAuthType = findOptionalLongAuthorizationListEntry(authorizationMap, tag);
337     return userAuthType.map(AuthorizationList::userAuthTypeToEnum);
338   }
339 
340   // Visible for testing.
userAuthTypeToEnum(long userAuthType)341   static Set<UserAuthType> userAuthTypeToEnum(long userAuthType) {
342     if (userAuthType == 0) {
343       return Set.of(USER_AUTH_TYPE_NONE);
344     }
345 
346     Set<UserAuthType> result = new HashSet<>();
347 
348     if ((userAuthType & 1L) == 1L) {
349       result.add(PASSWORD);
350     }
351     if ((userAuthType & 2L) == 2L) {
352       result.add(FINGERPRINT);
353     }
354     if (userAuthType == UINT32_MAX) {
355       result.add(USER_AUTH_TYPE_ANY);
356     }
357 
358     if (result.isEmpty()) {
359       throw new IllegalArgumentException("Invalid User Auth Type.");
360     }
361 
362     return result;
363   }
364 
userAuthTypeToLong(Set<UserAuthType> userAuthType)365   private static Long userAuthTypeToLong(Set<UserAuthType> userAuthType) {
366     if (userAuthType.contains(USER_AUTH_TYPE_NONE)) {
367       return 0L;
368     }
369 
370     Long result = 0L;
371 
372     for (UserAuthType type : userAuthType) {
373       switch (type) {
374         case PASSWORD:
375           result |= 1L;
376           break;
377         case FINGERPRINT:
378           result |= 2L;
379           break;
380         case USER_AUTH_TYPE_ANY:
381           result |= UINT32_MAX;
382           break;
383         default:
384           break;
385       }
386     }
387 
388     if (result == 0) {
389       throw new IllegalArgumentException("Invalid User Auth Type.");
390     }
391 
392     return result;
393   }
394 
toAsn1Sequence()395   public ASN1Sequence toAsn1Sequence() {
396     ASN1EncodableVector vector = new ASN1EncodableVector();
397     addOptionalIntegerSet(KM_TAG_PURPOSE, this.purpose, vector);
398     addOptionalInteger(KM_TAG_ALGORITHM, this.algorithm, vector);
399     addOptionalInteger(KM_TAG_KEY_SIZE, this.keySize, vector);
400     addOptionalIntegerSet(KM_TAG_DIGEST, this.digest, vector);
401     addOptionalIntegerSet(KM_TAG_PADDING, this.padding, vector);
402     addOptionalInteger(KM_TAG_EC_CURVE, this.ecCurve, vector);
403     addOptionalLong(KM_TAG_RSA_PUBLIC_EXPONENT, this.rsaPublicExponent, vector);
404     addBoolean(KM_TAG_ROLLBACK_RESISTANCE, this.rollbackResistance, vector);
405     addOptionalInstant(KM_TAG_ACTIVE_DATE_TIME, this.activeDateTime, vector);
406     addOptionalInstant(KM_TAG_ORIGINATION_EXPIRE_DATE_TIME, this.originationExpireDateTime, vector);
407     addOptionalInstant(KM_TAG_USAGE_EXPIRE_DATE_TIME, this.usageExpireDateTime, vector);
408     addBoolean(KM_TAG_NO_AUTH_REQUIRED, this.noAuthRequired, vector);
409     addOptionalUserAuthType(KM_TAG_USER_AUTH_TYPE, this.userAuthType, vector);
410     addOptionalDuration(KM_TAG_AUTH_TIMEOUT, this.authTimeout, vector);
411     addBoolean(KM_TAG_ALLOW_WHILE_ON_BODY, this.allowWhileOnBody, vector);
412     addBoolean(KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED, this.trustedUserPresenceRequired, vector);
413     addBoolean(KM_TAG_TRUSTED_CONFIRMATION_REQUIRED, this.trustedConfirmationRequired, vector);
414     addBoolean(KM_TAG_UNLOCKED_DEVICE_REQUIRED, this.unlockedDeviceRequired, vector);
415     addBoolean(KM_TAG_ALL_APPLICATIONS, this.allApplications, vector);
416     addOptionalOctetString(KM_TAG_APPLICATION_ID, this.applicationId, vector);
417     addOptionalInstant(KM_TAG_CREATION_DATE_TIME, this.creationDateTime, vector);
418     addOptionalInteger(KM_TAG_ORIGIN, this.origin, vector);
419     addBoolean(KM_TAG_ROLLBACK_RESISTANT, this.rollbackResistant, vector);
420     addOptionalRootOfTrust(KM_TAG_ROOT_OF_TRUST, this.rootOfTrust, vector);
421     addOptionalInteger(KM_TAG_OS_VERSION, this.osVersion, vector);
422     addOptionalInteger(KM_TAG_OS_PATCH_LEVEL, this.osPatchLevel, vector);
423     addOptionalOctetString(
424         KM_TAG_ATTESTATION_APPLICATION_ID, this.attestationApplicationIdBytes, vector);
425     addOptionalOctetString(KM_TAG_ATTESTATION_ID_BRAND, this.attestationIdBrand, vector);
426     addOptionalOctetString(KM_TAG_ATTESTATION_ID_DEVICE, this.attestationIdDevice, vector);
427     addOptionalOctetString(KM_TAG_ATTESTATION_ID_PRODUCT, this.attestationIdProduct, vector);
428     addOptionalOctetString(KM_TAG_ATTESTATION_ID_SERIAL, this.attestationIdSerial, vector);
429     addOptionalOctetString(KM_TAG_ATTESTATION_ID_IMEI, this.attestationIdImei, vector);
430     addOptionalOctetString(KM_TAG_ATTESTATION_ID_MEID, this.attestationIdMeid, vector);
431     addOptionalOctetString(
432         KM_TAG_ATTESTATION_ID_MANUFACTURER, this.attestationIdManufacturer, vector);
433     addOptionalOctetString(KM_TAG_ATTESTATION_ID_MODEL, this.attestationIdModel, vector);
434     addOptionalInteger(KM_TAG_VENDOR_PATCH_LEVEL, this.vendorPatchLevel, vector);
435     addOptionalInteger(KM_TAG_BOOT_PATCH_LEVEL, this.bootPatchLevel, vector);
436     addBoolean(KM_TAG_DEVICE_UNIQUE_ATTESTATION, this.individualAttestation, vector);
437     return new DERSequence(vector);
438   }
439 
addOptionalIntegerSet( int tag, Optional<Set<Integer>> entry, ASN1EncodableVector vector)440   private static void addOptionalIntegerSet(
441       int tag, Optional<Set<Integer>> entry, ASN1EncodableVector vector) {
442     if (entry.isPresent()) {
443       ASN1EncodableVector tmp = new ASN1EncodableVector();
444       entry.get().forEach((Integer value) -> tmp.add(new ASN1Integer(value.longValue())));
445       vector.add(new DERTaggedObject(tag, new DERSet(tmp)));
446     }
447   }
448 
addOptionalInstant( int tag, Optional<Instant> entry, ASN1EncodableVector vector)449   private static void addOptionalInstant(
450       int tag, Optional<Instant> entry, ASN1EncodableVector vector) {
451     if (entry.isPresent()) {
452       vector.add(new DERTaggedObject(tag, new ASN1Integer(entry.get().toEpochMilli())));
453     }
454   }
455 
addOptionalDuration( int tag, Optional<Duration> entry, ASN1EncodableVector vector)456   private static void addOptionalDuration(
457       int tag, Optional<Duration> entry, ASN1EncodableVector vector) {
458     if (entry.isPresent()) {
459       vector.add(new DERTaggedObject(tag, new ASN1Integer(entry.get().getSeconds())));
460     }
461   }
462 
addBoolean(int tag, boolean entry, ASN1EncodableVector vector)463   private static void addBoolean(int tag, boolean entry, ASN1EncodableVector vector) {
464     if (entry) {
465       vector.add(new DERTaggedObject(tag, DERNull.INSTANCE));
466     }
467   }
468 
addOptionalInteger( int tag, Optional<Integer> entry, ASN1EncodableVector vector)469   private static void addOptionalInteger(
470       int tag, Optional<Integer> entry, ASN1EncodableVector vector) {
471     if (entry.isPresent()) {
472       vector.add(new DERTaggedObject(tag, new ASN1Integer(entry.get())));
473     }
474   }
475 
addOptionalLong(int tag, Optional<Long> entry, ASN1EncodableVector vector)476   private static void addOptionalLong(int tag, Optional<Long> entry, ASN1EncodableVector vector) {
477     if (entry.isPresent()) {
478       vector.add(new DERTaggedObject(tag, new ASN1Integer(entry.get())));
479     }
480   }
481 
addOptionalOctetString( int tag, Optional<byte[]> entry, ASN1EncodableVector vector)482   private static void addOptionalOctetString(
483       int tag, Optional<byte[]> entry, ASN1EncodableVector vector) {
484     if (entry.isPresent()) {
485       vector.add(new DERTaggedObject(tag, new DEROctetString(entry.get())));
486     }
487   }
488 
addOptionalUserAuthType( int tag, Optional<Set<UserAuthType>> entry, ASN1EncodableVector vector)489   private static void addOptionalUserAuthType(
490       int tag, Optional<Set<UserAuthType>> entry, ASN1EncodableVector vector) {
491     if (entry.isPresent()) {
492       vector.add(new DERTaggedObject(tag, new ASN1Integer(userAuthTypeToLong(entry.get()))));
493     }
494   }
495 
addOptionalRootOfTrust( int tag, Optional<RootOfTrust> entry, ASN1EncodableVector vector)496   private static void addOptionalRootOfTrust(
497       int tag, Optional<RootOfTrust> entry, ASN1EncodableVector vector) {
498     if (entry.isPresent()) {
499       vector.add(new DERTaggedObject(tag, entry.get().toAsn1Sequence()));
500     }
501   }
502 
builder()503   public static Builder builder() {
504     return new Builder();
505   }
506 
507   /**
508    * Builder for an AuthorizationList. Any field not set will be made an Optional.empty or set with
509    * the default value.
510    */
511   public static final class Builder {
512 
513     Set<Integer> purpose;
514     Integer algorithm;
515     Integer keySize;
516     Set<Integer> digest;
517     Set<Integer> padding;
518     Integer ecCurve;
519     Long rsaPublicExponent;
520     boolean rollbackResistance;
521     Instant activeDateTime;
522     Instant originationExpireDateTime;
523     Instant usageExpireDateTime;
524     boolean noAuthRequired;
525     Set<UserAuthType> userAuthType;
526     Duration authTimeout;
527     boolean allowWhileOnBody;
528     boolean trustedUserPresenceRequired;
529     boolean trustedConfirmationRequired;
530     boolean unlockedDeviceRequired;
531     boolean allApplications;
532     byte[] applicationId;
533     Instant creationDateTime;
534     Integer origin;
535     boolean rollbackResistant;
536     RootOfTrust rootOfTrust;
537     Integer osVersion;
538     Integer osPatchLevel;
539     AttestationApplicationId attestationApplicationId;
540     byte[] attestationApplicationIdBytes;
541     byte[] attestationIdBrand;
542     byte[] attestationIdDevice;
543     byte[] attestationIdProduct;
544     byte[] attestationIdSerial;
545     byte[] attestationIdImei;
546     byte[] attestationIdMeid;
547     byte[] attestationIdManufacturer;
548     byte[] attestationIdModel;
549     Integer vendorPatchLevel;
550     Integer bootPatchLevel;
551     boolean individualAttestation;
552 
setPurpose(Set<Integer> purpose)553     public Builder setPurpose(Set<Integer> purpose) {
554       this.purpose = purpose;
555       return this;
556     }
557 
setAlgorithm(Integer algorithm)558     public Builder setAlgorithm(Integer algorithm) {
559       this.algorithm = algorithm;
560       return this;
561     }
562 
setKeySize(Integer keySize)563     public Builder setKeySize(Integer keySize) {
564       this.keySize = keySize;
565       return this;
566     }
567 
setDigest(Set<Integer> digest)568     public Builder setDigest(Set<Integer> digest) {
569       this.digest = digest;
570       return this;
571     }
572 
setPadding(Set<Integer> padding)573     public Builder setPadding(Set<Integer> padding) {
574       this.padding = padding;
575       return this;
576     }
577 
setEcCurve(Integer ecCurve)578     public Builder setEcCurve(Integer ecCurve) {
579       this.ecCurve = ecCurve;
580       return this;
581     }
582 
setRsaPublicExponent(Long rsaPublicExponent)583     public Builder setRsaPublicExponent(Long rsaPublicExponent) {
584       this.rsaPublicExponent = rsaPublicExponent;
585       return this;
586     }
587 
setRollbackResistance(boolean rollbackResistance)588     public Builder setRollbackResistance(boolean rollbackResistance) {
589       this.rollbackResistance = rollbackResistance;
590       return this;
591     }
592 
setActiveDateTime(Instant activeDateTime)593     public Builder setActiveDateTime(Instant activeDateTime) {
594       this.activeDateTime = activeDateTime;
595       return this;
596     }
597 
setOriginationExpireDateTime(Instant originationExpireDateTime)598     public Builder setOriginationExpireDateTime(Instant originationExpireDateTime) {
599       this.originationExpireDateTime = originationExpireDateTime;
600       return this;
601     }
602 
setUsageExpireDateTime(Instant usageExpireDateTime)603     public Builder setUsageExpireDateTime(Instant usageExpireDateTime) {
604       this.usageExpireDateTime = usageExpireDateTime;
605       return this;
606     }
607 
setNoAuthRequired(boolean noAuthRequired)608     public Builder setNoAuthRequired(boolean noAuthRequired) {
609       this.noAuthRequired = noAuthRequired;
610       return this;
611     }
612 
setUserAuthType(Set<UserAuthType> userAuthType)613     public Builder setUserAuthType(Set<UserAuthType> userAuthType) {
614       this.userAuthType = userAuthType;
615       return this;
616     }
617 
setAuthTimeout(Duration authTimeout)618     public Builder setAuthTimeout(Duration authTimeout) {
619       this.authTimeout = authTimeout;
620       return this;
621     }
622 
setAllowWhileOnBody(boolean allowWhileOnBody)623     public Builder setAllowWhileOnBody(boolean allowWhileOnBody) {
624       this.allowWhileOnBody = allowWhileOnBody;
625       return this;
626     }
627 
setTrustedUserPresenceRequired(boolean trustedUserPresenceRequired)628     public Builder setTrustedUserPresenceRequired(boolean trustedUserPresenceRequired) {
629       this.trustedUserPresenceRequired = trustedUserPresenceRequired;
630       return this;
631     }
632 
setTrustedConfirmationRequired(boolean trustedConfirmationRequired)633     public Builder setTrustedConfirmationRequired(boolean trustedConfirmationRequired) {
634       this.trustedConfirmationRequired = trustedConfirmationRequired;
635       return this;
636     }
637 
setUnlockedDeviceRequired(boolean unlockedDeviceRequired)638     public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
639       this.unlockedDeviceRequired = unlockedDeviceRequired;
640       return this;
641     }
642 
setAllApplications(boolean allApplications)643     public Builder setAllApplications(boolean allApplications) {
644       this.allApplications = allApplications;
645       return this;
646     }
647 
setApplicationId(byte[] applicationId)648     public Builder setApplicationId(byte[] applicationId) {
649       this.applicationId = applicationId;
650       return this;
651     }
652 
setCreationDateTime(Instant creationDateTime)653     public Builder setCreationDateTime(Instant creationDateTime) {
654       this.creationDateTime = creationDateTime;
655       return this;
656     }
657 
setOrigin(Integer origin)658     public Builder setOrigin(Integer origin) {
659       this.origin = origin;
660       return this;
661     }
662 
setRollbackResistant(boolean rollbackResistant)663     public Builder setRollbackResistant(boolean rollbackResistant) {
664       this.rollbackResistant = rollbackResistant;
665       return this;
666     }
667 
setRootOfTrust(RootOfTrust rootOfTrust)668     public Builder setRootOfTrust(RootOfTrust rootOfTrust) {
669       this.rootOfTrust = rootOfTrust;
670       return this;
671     }
672 
setOsVersion(Integer osVersion)673     public Builder setOsVersion(Integer osVersion) {
674       this.osVersion = osVersion;
675       return this;
676     }
677 
setOsPatchLevel(Integer osPatchLevel)678     public Builder setOsPatchLevel(Integer osPatchLevel) {
679       this.osPatchLevel = osPatchLevel;
680       return this;
681     }
682 
setAttestationApplicationId(AttestationApplicationId attestationApplicationId)683     public Builder setAttestationApplicationId(AttestationApplicationId attestationApplicationId) {
684       this.attestationApplicationId = attestationApplicationId;
685       return this;
686     }
687 
setAttestationApplicationIdBytes(byte[] attestationApplicationIdBytes)688     public Builder setAttestationApplicationIdBytes(byte[] attestationApplicationIdBytes) {
689       this.attestationApplicationIdBytes = attestationApplicationIdBytes;
690       return this;
691     }
692 
setAttestationIdBrand(byte[] attestationIdBrand)693     public Builder setAttestationIdBrand(byte[] attestationIdBrand) {
694       this.attestationIdBrand = attestationIdBrand;
695       return this;
696     }
697 
setAttestationIdProduct(byte[] attestationIdProduct)698     public Builder setAttestationIdProduct(byte[] attestationIdProduct) {
699       this.attestationIdProduct = attestationIdProduct;
700       return this;
701     }
702 
setAttestationIdSerial(byte[] attestationIdSerial)703     public Builder setAttestationIdSerial(byte[] attestationIdSerial) {
704       this.attestationIdSerial = attestationIdSerial;
705       return this;
706     }
707 
setAttestationIdImei(byte[] attestationIdImei)708     public Builder setAttestationIdImei(byte[] attestationIdImei) {
709       this.attestationIdImei = attestationIdImei;
710       return this;
711     }
712 
setAttestationIdMeid(byte[] attestationIdMeid)713     public Builder setAttestationIdMeid(byte[] attestationIdMeid) {
714       this.attestationIdMeid = attestationIdMeid;
715       return this;
716     }
717 
setAttestationIdManufacturer(byte[] attestationIdManufacturer)718     public Builder setAttestationIdManufacturer(byte[] attestationIdManufacturer) {
719       this.attestationIdManufacturer = attestationIdManufacturer;
720       return this;
721     }
722 
setAttestationIdModel(byte[] attestationIdModel)723     public Builder setAttestationIdModel(byte[] attestationIdModel) {
724       this.attestationIdModel = attestationIdModel;
725       return this;
726     }
727 
setVendorPatchLevel(Integer vendorPatchLevel)728     public Builder setVendorPatchLevel(Integer vendorPatchLevel) {
729       this.vendorPatchLevel = vendorPatchLevel;
730       return this;
731     }
732 
setBootPatchLevel(Integer bootPatchLevel)733     public Builder setBootPatchLevel(Integer bootPatchLevel) {
734       this.bootPatchLevel = bootPatchLevel;
735       return this;
736     }
737 
setIndividualAttestation(boolean individualAttestation)738     public Builder setIndividualAttestation(boolean individualAttestation) {
739       this.individualAttestation = individualAttestation;
740       return this;
741     }
742 
build()743     public AuthorizationList build() {
744       return new AuthorizationList(this);
745     }
746   }
747 }
748