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