1 /* 2 * Copyright (C) 2016 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.keystore.cts; 18 19 import static com.google.common.base.Functions.forMap; 20 import static com.google.common.collect.Collections2.transform; 21 22 import android.security.keystore.KeyProperties; 23 import android.util.Log; 24 25 import com.google.common.base.Joiner; 26 import com.google.common.collect.ImmutableMap; 27 import com.google.common.collect.ImmutableSet; 28 import com.google.common.collect.Lists; 29 30 import org.bouncycastle.asn1.ASN1Encodable; 31 import org.bouncycastle.asn1.ASN1Primitive; 32 import org.bouncycastle.asn1.ASN1Sequence; 33 import org.bouncycastle.asn1.ASN1SequenceParser; 34 import org.bouncycastle.asn1.ASN1TaggedObject; 35 36 import java.io.IOException; 37 import java.io.UnsupportedEncodingException; 38 import java.security.cert.CertificateParsingException; 39 import java.text.DateFormat; 40 import java.util.Collection; 41 import java.util.Date; 42 import java.util.List; 43 import java.util.Set; 44 45 import co.nstant.in.cbor.model.DataItem; 46 import co.nstant.in.cbor.model.Number; 47 48 public class AuthorizationList { 49 // Algorithm values. 50 public static final int KM_ALGORITHM_RSA = 1; 51 public static final int KM_ALGORITHM_EC = 3; 52 53 // EC Curves 54 public static final int KM_EC_CURVE_P224 = 0; 55 public static final int KM_EC_CURVE_P256 = 1; 56 public static final int KM_EC_CURVE_P384 = 2; 57 public static final int KM_EC_CURVE_P521 = 3; 58 public static final int KM_EC_CURVE_25519 = 4; 59 60 // Padding modes. 61 public static final int KM_PAD_NONE = 1; 62 public static final int KM_PAD_RSA_OAEP = 2; 63 public static final int KM_PAD_RSA_PSS = 3; 64 public static final int KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4; 65 public static final int KM_PAD_RSA_PKCS1_1_5_SIGN = 5; 66 67 // Digest modes. 68 public static final int KM_DIGEST_NONE = 0; 69 public static final int KM_DIGEST_MD5 = 1; 70 public static final int KM_DIGEST_SHA1 = 2; 71 public static final int KM_DIGEST_SHA_2_224 = 3; 72 public static final int KM_DIGEST_SHA_2_256 = 4; 73 public static final int KM_DIGEST_SHA_2_384 = 5; 74 public static final int KM_DIGEST_SHA_2_512 = 6; 75 76 // Key origins. 77 public static final int KM_ORIGIN_GENERATED = 0; 78 public static final int KM_ORIGIN_IMPORTED = 2; 79 public static final int KM_ORIGIN_UNKNOWN = 3; 80 81 // Operation Purposes. 82 public static final int KM_PURPOSE_ENCRYPT = 0; 83 public static final int KM_PURPOSE_DECRYPT = 1; 84 public static final int KM_PURPOSE_SIGN = 2; 85 public static final int KM_PURPOSE_VERIFY = 3; 86 87 // User authenticators. 88 public static final int HW_AUTH_PASSWORD = 1 << 0; 89 public static final int HW_AUTH_FINGERPRINT = 1 << 1; 90 91 // Keymaster tag classes 92 private static final int KM_ENUM = 1 << 28; 93 private static final int KM_ENUM_REP = 2 << 28; 94 private static final int KM_UINT = 3 << 28; 95 private static final int KM_ULONG = 5 << 28; 96 private static final int KM_DATE = 6 << 28; 97 private static final int KM_BOOL = 7 << 28; 98 private static final int KM_BYTES = 9 << 28; 99 100 // Tag class removal mask 101 private static final int KEYMASTER_TAG_TYPE_MASK = 0x0FFFFFFF; 102 103 // Keymaster tags 104 private static final int KM_TAG_PURPOSE = KM_ENUM_REP | 1; 105 private static final int KM_TAG_ALGORITHM = KM_ENUM | 2; 106 private static final int KM_TAG_KEY_SIZE = KM_UINT | 3; 107 private static final int KM_TAG_DIGEST = KM_ENUM_REP | 5; 108 private static final int KM_TAG_PADDING = KM_ENUM_REP | 6; 109 private static final int KM_TAG_EC_CURVE = KM_ENUM | 10; 110 private static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_ULONG | 200; 111 private static final int KM_TAG_RSA_OAEP_MGF_DIGEST = KM_ENUM | 203; 112 private static final int KM_TAG_ROLLBACK_RESISTANCE = KM_BOOL | 303; 113 private static final int KM_TAG_ACTIVE_DATETIME = KM_DATE | 400; 114 private static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401; 115 private static final int KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402; 116 private static final int KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503; 117 private static final int KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504; 118 private static final int KM_TAG_AUTH_TIMEOUT = KM_UINT | 505; 119 private static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506; 120 private static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507; 121 private static final int KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = KM_BOOL | 508; 122 private static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509; 123 private static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600; 124 private static final int KM_TAG_CREATION_DATETIME = KM_DATE | 701; 125 private static final int KM_TAG_ORIGIN = KM_ENUM | 702; 126 private static final int KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703; 127 private static final int KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704; 128 private static final int KM_TAG_OS_VERSION = KM_UINT | 705; 129 private static final int KM_TAG_OS_PATCHLEVEL = KM_UINT | 706; 130 private static final int KM_TAG_ATTESTATION_APPLICATION_ID = KM_BYTES | 709; 131 private static final int KM_TAG_ATTESTATION_ID_BRAND = KM_BYTES | 710; 132 private static final int KM_TAG_ATTESTATION_ID_DEVICE = KM_BYTES | 711; 133 private static final int KM_TAG_ATTESTATION_ID_PRODUCT = KM_BYTES | 712; 134 private static final int KM_TAG_ATTESTATION_ID_SERIAL = KM_BYTES | 713; 135 private static final int KM_TAG_ATTESTATION_ID_IMEI = KM_BYTES | 714; 136 private static final int KM_TAG_ATTESTATION_ID_MEID = KM_BYTES | 715; 137 private static final int KM_TAG_ATTESTATION_ID_MANUFACTURER = KM_BYTES | 716; 138 private static final int KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717; 139 private static final int KM_TAG_VENDOR_PATCHLEVEL = KM_UINT | 718; 140 private static final int KM_TAG_BOOT_PATCHLEVEL = KM_UINT | 719; 141 private static final int KM_TAG_ATTESTATION_ID_SECOND_IMEI = KM_BYTES | 723; 142 143 // Map for converting padding values to strings 144 private static final ImmutableMap<Integer, String> paddingMap = ImmutableMap 145 .<Integer, String> builder() 146 .put(KM_PAD_NONE, "NONE") 147 .put(KM_PAD_RSA_OAEP, "OAEP") 148 .put(KM_PAD_RSA_PSS, "PSS") 149 .put(KM_PAD_RSA_PKCS1_1_5_ENCRYPT, "PKCS1 ENCRYPT") 150 .put(KM_PAD_RSA_PKCS1_1_5_SIGN, "PKCS1 SIGN") 151 .build(); 152 153 // Map for converting digest values to strings 154 private static final ImmutableMap<Integer, String> digestMap = ImmutableMap 155 .<Integer, String> builder() 156 .put(KM_DIGEST_NONE, "NONE") 157 .put(KM_DIGEST_MD5, "MD5") 158 .put(KM_DIGEST_SHA1, "SHA1") 159 .put(KM_DIGEST_SHA_2_224, "SHA224") 160 .put(KM_DIGEST_SHA_2_256, "SHA256") 161 .put(KM_DIGEST_SHA_2_384, "SHA384") 162 .put(KM_DIGEST_SHA_2_512, "SHA512") 163 .build(); 164 165 // Map for converting purpose values to strings 166 private static final ImmutableMap<Integer, String> purposeMap = ImmutableMap 167 .<Integer, String> builder() 168 .put(KM_PURPOSE_DECRYPT, "DECRYPT") 169 .put(KM_PURPOSE_ENCRYPT, "ENCRYPT") 170 .put(KM_PURPOSE_SIGN, "SIGN") 171 .put(KM_PURPOSE_VERIFY, "VERIFY") 172 .build(); 173 174 private Integer securityLevel; 175 private Set<Integer> purposes; 176 private Integer algorithm; 177 private Integer keySize; 178 private Set<Integer> digests; 179 private Set<Integer> paddingModes; 180 private Integer ecCurve; 181 private Long rsaPublicExponent; 182 private Set<Integer> mRsaOaepMgfDigests; 183 private Date activeDateTime; 184 private Date originationExpireDateTime; 185 private Date usageExpireDateTime; 186 private boolean noAuthRequired; 187 private Integer userAuthType; 188 private Integer authTimeout; 189 private boolean allowWhileOnBody; 190 private boolean allApplications; 191 private byte[] applicationId; 192 private Date creationDateTime; 193 private Integer origin; 194 private boolean rollbackResistant; 195 private boolean rollbackResistance; 196 private RootOfTrust rootOfTrust; 197 private Integer osVersion; 198 private Integer osPatchLevel; 199 private Integer vendorPatchLevel; 200 private Integer bootPatchLevel; 201 private AttestationApplicationId attestationApplicationId; 202 private String brand; 203 private String device; 204 private String serialNumber; 205 private String imei; 206 private String meid; 207 private String product; 208 private String manufacturer; 209 private String model; 210 private boolean userPresenceRequired; 211 private boolean confirmationRequired; 212 private String mSecondImei; 213 AuthorizationList(ASN1Encodable sequence, int attestationVersion)214 public AuthorizationList(ASN1Encodable sequence, int attestationVersion) throws CertificateParsingException { 215 this(sequence, attestationVersion, true); 216 } 217 AuthorizationList(ASN1Encodable sequence, int attestationVersion, boolean strictParsing)218 public AuthorizationList(ASN1Encodable sequence, int attestationVersion, boolean strictParsing) throws CertificateParsingException { 219 if (!(sequence instanceof ASN1Sequence)) { 220 throw new CertificateParsingException("Expected sequence for authorization list, found " 221 + sequence.getClass().getName()); 222 } 223 224 ASN1SequenceParser parser = ((ASN1Sequence) sequence).parser(); 225 ASN1TaggedObject entry = parseAsn1TaggedObject(parser); 226 int currentTag = 0, prevTag = 0; 227 for (; entry != null; entry = parseAsn1TaggedObject(parser)) { 228 prevTag = currentTag; 229 currentTag = entry.getTagNo(); 230 if (prevTag > currentTag) { 231 throw new CertificateParsingException( 232 "Incorrect order of tags in authorization list: " + currentTag); 233 } 234 ASN1Primitive value = entry.getObject(); 235 Log.i("Attestation", "Parsing tag: [" + currentTag + "], value: [" + value + "]"); 236 switch (currentTag) { 237 default: 238 throw new CertificateParsingException("Unknown tag " + currentTag + " found"); 239 240 case KM_TAG_PURPOSE & KEYMASTER_TAG_TYPE_MASK: 241 purposes = Asn1Utils.getIntegersFromAsn1Set(value); 242 break; 243 case KM_TAG_ALGORITHM & KEYMASTER_TAG_TYPE_MASK: 244 algorithm = Asn1Utils.getIntegerFromAsn1(value); 245 break; 246 case KM_TAG_KEY_SIZE & KEYMASTER_TAG_TYPE_MASK: 247 keySize = Asn1Utils.getIntegerFromAsn1(value); 248 Log.i("Attestation", "Found KEY SIZE, value: " + keySize); 249 break; 250 case KM_TAG_DIGEST & KEYMASTER_TAG_TYPE_MASK: 251 digests = Asn1Utils.getIntegersFromAsn1Set(value); 252 break; 253 case KM_TAG_PADDING & KEYMASTER_TAG_TYPE_MASK: 254 paddingModes = Asn1Utils.getIntegersFromAsn1Set(value); 255 break; 256 case KM_TAG_RSA_PUBLIC_EXPONENT & KEYMASTER_TAG_TYPE_MASK: 257 rsaPublicExponent = Asn1Utils.getLongFromAsn1(value); 258 break; 259 case KM_TAG_RSA_OAEP_MGF_DIGEST & KEYMASTER_TAG_TYPE_MASK: 260 mRsaOaepMgfDigests = Asn1Utils.getIntegersFromAsn1Set(value); 261 break; 262 case KM_TAG_NO_AUTH_REQUIRED & KEYMASTER_TAG_TYPE_MASK: 263 noAuthRequired = true; 264 break; 265 case KM_TAG_CREATION_DATETIME & KEYMASTER_TAG_TYPE_MASK: 266 creationDateTime = Asn1Utils.getDateFromAsn1(value); 267 break; 268 case KM_TAG_ORIGIN & KEYMASTER_TAG_TYPE_MASK: 269 origin = Asn1Utils.getIntegerFromAsn1(value); 270 break; 271 case KM_TAG_OS_VERSION & KEYMASTER_TAG_TYPE_MASK: 272 osVersion = Asn1Utils.getIntegerFromAsn1(value); 273 break; 274 case KM_TAG_OS_PATCHLEVEL & KEYMASTER_TAG_TYPE_MASK: 275 osPatchLevel = Asn1Utils.getIntegerFromAsn1(value); 276 break; 277 case KM_TAG_VENDOR_PATCHLEVEL & KEYMASTER_TAG_TYPE_MASK: 278 vendorPatchLevel = Asn1Utils.getIntegerFromAsn1(value); 279 break; 280 case KM_TAG_BOOT_PATCHLEVEL & KEYMASTER_TAG_TYPE_MASK: 281 bootPatchLevel = Asn1Utils.getIntegerFromAsn1(value); 282 break; 283 case KM_TAG_ACTIVE_DATETIME & KEYMASTER_TAG_TYPE_MASK: 284 activeDateTime = Asn1Utils.getDateFromAsn1(value); 285 break; 286 case KM_TAG_ORIGINATION_EXPIRE_DATETIME & KEYMASTER_TAG_TYPE_MASK: 287 originationExpireDateTime = Asn1Utils.getDateFromAsn1(value); 288 break; 289 case KM_TAG_USAGE_EXPIRE_DATETIME & KEYMASTER_TAG_TYPE_MASK: 290 usageExpireDateTime = Asn1Utils.getDateFromAsn1(value); 291 break; 292 case KM_TAG_ROLLBACK_RESISTANT & KEYMASTER_TAG_TYPE_MASK: 293 rollbackResistant = true; 294 break; 295 case KM_TAG_ROLLBACK_RESISTANCE & KEYMASTER_TAG_TYPE_MASK: 296 rollbackResistance = true; 297 break; 298 case KM_TAG_AUTH_TIMEOUT & KEYMASTER_TAG_TYPE_MASK: 299 authTimeout = Asn1Utils.getIntegerFromAsn1(value); 300 break; 301 case KM_TAG_ALLOW_WHILE_ON_BODY & KEYMASTER_TAG_TYPE_MASK: 302 allowWhileOnBody = true; 303 break; 304 case KM_TAG_EC_CURVE & KEYMASTER_TAG_TYPE_MASK: 305 ecCurve = Asn1Utils.getIntegerFromAsn1(value); 306 break; 307 case KM_TAG_USER_AUTH_TYPE & KEYMASTER_TAG_TYPE_MASK: 308 userAuthType = Asn1Utils.getIntegerFromAsn1(value); 309 break; 310 case KM_TAG_ROOT_OF_TRUST & KEYMASTER_TAG_TYPE_MASK: 311 rootOfTrust = new RootOfTrust(value, attestationVersion, strictParsing); 312 break; 313 case KM_TAG_ATTESTATION_APPLICATION_ID & KEYMASTER_TAG_TYPE_MASK: 314 attestationApplicationId = new AttestationApplicationId(Asn1Utils 315 .getAsn1EncodableFromBytes(Asn1Utils.getByteArrayFromAsn1(value))); 316 break; 317 case KM_TAG_ATTESTATION_ID_BRAND & KEYMASTER_TAG_TYPE_MASK: 318 brand = getStringFromAsn1Value(value); 319 break; 320 case KM_TAG_ATTESTATION_ID_DEVICE & KEYMASTER_TAG_TYPE_MASK: 321 device = getStringFromAsn1Value(value); 322 break; 323 case KM_TAG_ATTESTATION_ID_PRODUCT & KEYMASTER_TAG_TYPE_MASK: 324 product = getStringFromAsn1Value(value); 325 break; 326 case KM_TAG_ATTESTATION_ID_SERIAL & KEYMASTER_TAG_TYPE_MASK: 327 serialNumber = getStringFromAsn1Value(value); 328 break; 329 case KM_TAG_ATTESTATION_ID_IMEI & KEYMASTER_TAG_TYPE_MASK: 330 imei = getStringFromAsn1Value(value); 331 break; 332 case KM_TAG_ATTESTATION_ID_MEID & KEYMASTER_TAG_TYPE_MASK: 333 meid = getStringFromAsn1Value(value); 334 break; 335 case KM_TAG_ATTESTATION_ID_MANUFACTURER & KEYMASTER_TAG_TYPE_MASK: 336 manufacturer = getStringFromAsn1Value(value); 337 break; 338 case KM_TAG_ATTESTATION_ID_MODEL & KEYMASTER_TAG_TYPE_MASK: 339 model = getStringFromAsn1Value(value); 340 break; 341 case KM_TAG_ALL_APPLICATIONS & KEYMASTER_TAG_TYPE_MASK: 342 allApplications = true; 343 break; 344 case KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED & KEYMASTER_TAG_TYPE_MASK: 345 userPresenceRequired = true; 346 break; 347 case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED & KEYMASTER_TAG_TYPE_MASK: 348 confirmationRequired = true; 349 break; 350 case KM_TAG_ATTESTATION_ID_SECOND_IMEI & KEYMASTER_TAG_TYPE_MASK: 351 mSecondImei = getStringFromAsn1Value(value); 352 break; 353 } 354 } 355 356 } 357 AuthorizationList(co.nstant.in.cbor.model.Map submodMap)358 public AuthorizationList(co.nstant.in.cbor.model.Map submodMap) 359 throws CertificateParsingException { 360 for (DataItem key : submodMap.getKeys()) { 361 int keyInt = ((Number) key).getValue().intValue(); 362 switch (keyInt) { 363 default: 364 throw new CertificateParsingException("Unknown EAT tag: " + key); 365 366 case EatClaim.SECURITY_LEVEL: 367 securityLevel = eatSecurityLevelToKeymasterSecurityLevel( 368 CborUtils.getInt(submodMap, key)); 369 break; 370 case EatClaim.PURPOSE: 371 purposes = CborUtils.getIntSet(submodMap, key); 372 break; 373 case EatClaim.ALGORITHM: 374 algorithm = CborUtils.getInt(submodMap, key); 375 break; 376 case EatClaim.KEY_SIZE: 377 keySize = CborUtils.getInt(submodMap, key); 378 Log.i("Attestation", "Found KEY SIZE, value: " + keySize); 379 break; 380 case EatClaim.DIGEST: 381 digests = CborUtils.getIntSet(submodMap, key); 382 break; 383 case EatClaim.PADDING: 384 paddingModes = CborUtils.getIntSet(submodMap, key); 385 break; 386 case EatClaim.RSA_PUBLIC_EXPONENT: 387 rsaPublicExponent = CborUtils.getLong(submodMap, key); 388 break; 389 case EatClaim.RSA_OAEP_MGF_DIGEST: 390 mRsaOaepMgfDigests = CborUtils.getIntSet(submodMap, key); 391 break; 392 case EatClaim.NO_AUTH_REQUIRED: 393 noAuthRequired = true; 394 break; 395 case EatClaim.IAT: 396 creationDateTime = CborUtils.getDate(submodMap, key); 397 break; 398 case EatClaim.ORIGIN: 399 origin = CborUtils.getInt(submodMap, key); 400 break; 401 case EatClaim.OS_VERSION: 402 osVersion = CborUtils.getInt(submodMap, key); 403 break; 404 case EatClaim.OS_PATCHLEVEL: 405 osPatchLevel = CborUtils.getInt(submodMap, key); 406 break; 407 case EatClaim.VENDOR_PATCHLEVEL: 408 vendorPatchLevel = CborUtils.getInt(submodMap, key); 409 break; 410 case EatClaim.BOOT_PATCHLEVEL: 411 bootPatchLevel = CborUtils.getInt(submodMap, key); 412 break; 413 case EatClaim.ACTIVE_DATETIME: 414 activeDateTime = CborUtils.getDate(submodMap, key); 415 break; 416 case EatClaim.ORIGINATION_EXPIRE_DATETIME: 417 originationExpireDateTime = CborUtils.getDate(submodMap, key); 418 break; 419 case EatClaim.USAGE_EXPIRE_DATETIME: 420 usageExpireDateTime = CborUtils.getDate(submodMap, key); 421 break; 422 case EatClaim.ROLLBACK_RESISTANT: 423 rollbackResistant = true; 424 break; 425 case EatClaim.ROLLBACK_RESISTANCE: 426 rollbackResistance = true; 427 break; 428 case EatClaim.AUTH_TIMEOUT: 429 authTimeout = CborUtils.getInt(submodMap, key); 430 break; 431 case EatClaim.ALLOW_WHILE_ON_BODY: 432 allowWhileOnBody = true; 433 break; 434 case EatClaim.EC_CURVE: 435 ecCurve = CborUtils.getInt(submodMap, key); 436 break; 437 case EatClaim.USER_AUTH_TYPE: 438 userAuthType = CborUtils.getInt(submodMap, key); 439 break; 440 case EatClaim.ATTESTATION_APPLICATION_ID: 441 // TODO: The attestation application ID is currently still encoded as an ASN.1 442 // structure. Parse a CBOR structure when it's available instead. 443 attestationApplicationId = new AttestationApplicationId( 444 Asn1Utils.getAsn1EncodableFromBytes(CborUtils.getBytes(submodMap, key))); 445 break; 446 case EatClaim.ATTESTATION_ID_BRAND: 447 brand = CborUtils.getString(submodMap, key); 448 break; 449 case EatClaim.ATTESTATION_ID_DEVICE: 450 device = CborUtils.getString(submodMap, key); 451 break; 452 case EatClaim.ATTESTATION_ID_PRODUCT: 453 product = CborUtils.getString(submodMap, key); 454 break; 455 case EatClaim.ATTESTATION_ID_SERIAL: 456 serialNumber = CborUtils.getString(submodMap, key); 457 break; 458 case EatClaim.UEID: 459 // TODO: Parse depending on encoding chosen in attestation_record.cpp. 460 imei = CborUtils.getString(submodMap, key); 461 break; 462 case EatClaim.ATTESTATION_ID_MEID: 463 meid = CborUtils.getString(submodMap, key); 464 break; 465 case EatClaim.ATTESTATION_ID_MANUFACTURER: 466 manufacturer = CborUtils.getString(submodMap, key); 467 break; 468 case EatClaim.ATTESTATION_ID_MODEL: 469 model = CborUtils.getString(submodMap, key); 470 break; 471 case EatClaim.USER_PRESENCE_REQUIRED: 472 userPresenceRequired = CborUtils.getBoolean(submodMap, key); 473 break; 474 case EatClaim.TRUSTED_CONFIRMATION_REQUIRED: 475 confirmationRequired = true; 476 break; 477 } 478 } 479 } 480 algorithmToString(int algorithm)481 public static String algorithmToString(int algorithm) { 482 switch (algorithm) { 483 case KM_ALGORITHM_RSA: 484 return "RSA"; 485 case KM_ALGORITHM_EC: 486 return "ECDSA"; 487 default: 488 return "Unknown"; 489 } 490 } 491 paddingModesToString(final Set<Integer> paddingModes)492 public static String paddingModesToString(final Set<Integer> paddingModes) { 493 return joinStrings(transform(paddingModes, forMap(paddingMap, "Unknown"))); 494 } 495 paddingModeToString(int paddingMode)496 public static String paddingModeToString(int paddingMode) { 497 return forMap(paddingMap, "Unknown").apply(paddingMode); 498 } 499 digestsToString(Set<Integer> digests)500 public static String digestsToString(Set<Integer> digests) { 501 return joinStrings(transform(digests, forMap(digestMap, "Unknown"))); 502 } 503 digestToString(int digest)504 public static String digestToString(int digest) { 505 return forMap(digestMap, "Unknown").apply(digest); 506 } 507 purposesToString(Set<Integer> purposes)508 public static String purposesToString(Set<Integer> purposes) { 509 return joinStrings(transform(purposes, forMap(purposeMap, "Unknown"))); 510 } 511 userAuthTypeToString(int userAuthType)512 public static String userAuthTypeToString(int userAuthType) { 513 List<String> types = Lists.newArrayList(); 514 if ((userAuthType & HW_AUTH_FINGERPRINT) != 0) 515 types.add("Fingerprint"); 516 if ((userAuthType & HW_AUTH_PASSWORD) != 0) 517 types.add("Password"); 518 return joinStrings(types); 519 } 520 originToString(int origin)521 public static String originToString(int origin) { 522 switch (origin) { 523 case KM_ORIGIN_GENERATED: 524 return "Generated"; 525 case KM_ORIGIN_IMPORTED: 526 return "Imported"; 527 case KM_ORIGIN_UNKNOWN: 528 return "Unknown (KM0)"; 529 default: 530 return "Unknown"; 531 } 532 } 533 joinStrings(Collection<String> collection)534 private static String joinStrings(Collection<String> collection) { 535 return new StringBuilder() 536 .append("[") 537 .append(Joiner.on(", ").join(collection)) 538 .append("]") 539 .toString(); 540 } 541 formatDate(Date date)542 private static String formatDate(Date date) { 543 return DateFormat.getDateTimeInstance().format(date); 544 } 545 parseAsn1TaggedObject(ASN1SequenceParser parser)546 private static ASN1TaggedObject parseAsn1TaggedObject(ASN1SequenceParser parser) 547 throws CertificateParsingException { 548 ASN1Encodable asn1Encodable = parseAsn1Encodable(parser); 549 if (asn1Encodable == null || asn1Encodable instanceof ASN1TaggedObject) { 550 return (ASN1TaggedObject) asn1Encodable; 551 } 552 throw new CertificateParsingException( 553 "Expected tagged object, found " + asn1Encodable.getClass().getName()); 554 } 555 parseAsn1Encodable(ASN1SequenceParser parser)556 private static ASN1Encodable parseAsn1Encodable(ASN1SequenceParser parser) 557 throws CertificateParsingException { 558 try { 559 return parser.readObject(); 560 } catch (IOException e) { 561 throw new CertificateParsingException("Failed to parse ASN1 sequence", e); 562 } 563 } 564 getSecurityLevel()565 public Integer getSecurityLevel() { 566 return securityLevel; 567 } 568 getPurposes()569 public Set<Integer> getPurposes() { 570 return purposes; 571 } 572 getAlgorithm()573 public Integer getAlgorithm() { 574 return algorithm; 575 } 576 getKeySize()577 public Integer getKeySize() { 578 return keySize; 579 } 580 getDigests()581 public Set<Integer> getDigests() { 582 return digests; 583 } 584 getPaddingModes()585 public Set<Integer> getPaddingModes() { 586 return paddingModes; 587 } 588 getPaddingModesAsStrings()589 public Set<String> getPaddingModesAsStrings() throws CertificateParsingException { 590 if (paddingModes == null) { 591 return ImmutableSet.of(); 592 } 593 594 ImmutableSet.Builder<String> builder = ImmutableSet.builder(); 595 for (int paddingMode : paddingModes) { 596 switch (paddingMode) { 597 case KM_PAD_NONE: 598 builder.add(KeyProperties.ENCRYPTION_PADDING_NONE); 599 break; 600 case KM_PAD_RSA_OAEP: 601 builder.add(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP); 602 break; 603 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT: 604 builder.add(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1); 605 break; 606 case KM_PAD_RSA_PKCS1_1_5_SIGN: 607 builder.add(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); 608 break; 609 case KM_PAD_RSA_PSS: 610 builder.add(KeyProperties.SIGNATURE_PADDING_RSA_PSS); 611 break; 612 default: 613 throw new CertificateParsingException("Invalid padding mode " + paddingMode); 614 } 615 } 616 return builder.build(); 617 } 618 getEcCurve()619 public Integer getEcCurve() { 620 return ecCurve; 621 } 622 ecCurveAsString()623 public String ecCurveAsString() { 624 if (ecCurve == null) 625 return "NULL"; 626 627 switch (ecCurve) { 628 case KM_EC_CURVE_P224: 629 return "secp224r1"; 630 case KM_EC_CURVE_P256: 631 return "secp256r1"; 632 case KM_EC_CURVE_P384: 633 return "secp384r1"; 634 case KM_EC_CURVE_P521: 635 return "secp521r1"; 636 case KM_EC_CURVE_25519: 637 return "CURVE_25519"; 638 default: 639 return "unknown"; 640 } 641 } 642 getRsaPublicExponent()643 public Long getRsaPublicExponent() { 644 return rsaPublicExponent; 645 } 646 getRsaOaepMgfDigests()647 public Set<Integer> getRsaOaepMgfDigests() { 648 return mRsaOaepMgfDigests; 649 } 650 getActiveDateTime()651 public Date getActiveDateTime() { 652 return activeDateTime; 653 } 654 getOriginationExpireDateTime()655 public Date getOriginationExpireDateTime() { 656 return originationExpireDateTime; 657 } 658 getUsageExpireDateTime()659 public Date getUsageExpireDateTime() { 660 return usageExpireDateTime; 661 } 662 isNoAuthRequired()663 public boolean isNoAuthRequired() { 664 return noAuthRequired; 665 } 666 getUserAuthType()667 public Integer getUserAuthType() { 668 return userAuthType; 669 } 670 getAuthTimeout()671 public Integer getAuthTimeout() { 672 return authTimeout; 673 } 674 isAllowWhileOnBody()675 public boolean isAllowWhileOnBody() { 676 return allowWhileOnBody; 677 } 678 isAllApplications()679 public boolean isAllApplications() { 680 return allApplications; 681 } 682 getApplicationId()683 public byte[] getApplicationId() { 684 return applicationId; 685 } 686 getCreationDateTime()687 public Date getCreationDateTime() { 688 return creationDateTime; 689 } 690 getOrigin()691 public Integer getOrigin() { 692 return origin; 693 } 694 isRollbackResistant()695 public boolean isRollbackResistant() { 696 return rollbackResistant; 697 } 698 isRollbackResistance()699 public boolean isRollbackResistance() { 700 return rollbackResistance; 701 } 702 getRootOfTrust()703 public RootOfTrust getRootOfTrust() { 704 return rootOfTrust; 705 } 706 getOsVersion()707 public Integer getOsVersion() { 708 return osVersion; 709 } 710 getOsPatchLevel()711 public Integer getOsPatchLevel() { 712 return osPatchLevel; 713 } 714 getVendorPatchLevel()715 public Integer getVendorPatchLevel() { 716 return vendorPatchLevel; 717 } 718 getBootPatchLevel()719 public Integer getBootPatchLevel() { 720 return bootPatchLevel; 721 } 722 getAttestationApplicationId()723 public AttestationApplicationId getAttestationApplicationId() { 724 return attestationApplicationId; 725 } 726 getBrand()727 public String getBrand() { 728 return brand; 729 } 730 getDevice()731 public String getDevice() { 732 return device; 733 } 734 getSerialNumber()735 public String getSerialNumber() { 736 return serialNumber; 737 }; 738 getImei()739 public String getImei() { 740 return imei; 741 }; 742 getMeid()743 public String getMeid() { 744 return meid; 745 }; 746 getProduct()747 public String getProduct() { 748 return product; 749 }; 750 getManufacturer()751 public String getManufacturer() { 752 return manufacturer; 753 }; 754 getModel()755 public String getModel() { 756 return model; 757 }; 758 isUserPresenceRequired()759 public boolean isUserPresenceRequired() { 760 return userPresenceRequired; 761 } 762 isConfirmationRequired()763 public boolean isConfirmationRequired() { 764 return confirmationRequired; 765 } 766 getSecondImei()767 public String getSecondImei() { 768 return mSecondImei; 769 }; 770 eatSecurityLevelToKeymasterSecurityLevel(int eatSecurityLevel)771 static int eatSecurityLevelToKeymasterSecurityLevel(int eatSecurityLevel) { 772 switch(eatSecurityLevel) { 773 case EatClaim.SECURITY_LEVEL_UNRESTRICTED: 774 return Attestation.KM_SECURITY_LEVEL_SOFTWARE; 775 case EatClaim.SECURITY_LEVEL_SECURE_RESTRICTED: 776 return Attestation.KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT; 777 case EatClaim.SECURITY_LEVEL_HARDWARE: 778 return Attestation.KM_SECURITY_LEVEL_STRONG_BOX; 779 default: 780 throw new RuntimeException("Invalid EAT security level: " + eatSecurityLevel); 781 } 782 } 783 getStringFromAsn1Value(ASN1Primitive value)784 private String getStringFromAsn1Value(ASN1Primitive value) throws CertificateParsingException { 785 try { 786 return Asn1Utils.getStringFromAsn1OctetStreamAssumingUTF8(value); 787 } catch (UnsupportedEncodingException e) { 788 throw new CertificateParsingException("Error parsing ASN.1 value", e); 789 } 790 } 791 792 @Override toString()793 public String toString() { 794 StringBuilder s = new StringBuilder(); 795 796 if (algorithm != null) { 797 s.append("\nAlgorithm: ").append(algorithmToString(algorithm)); 798 } 799 800 if (keySize != null) { 801 s.append("\nKeySize: ").append(keySize); 802 } 803 804 if (purposes != null && !purposes.isEmpty()) { 805 s.append("\nPurposes: ").append(purposesToString(purposes)); 806 } 807 808 if (digests != null && !digests.isEmpty()) { 809 s.append("\nDigests: ").append(digestsToString(digests)); 810 } 811 812 if (paddingModes != null && !paddingModes.isEmpty()) { 813 s.append("\nPadding modes: ").append(paddingModesToString(paddingModes)); 814 } 815 816 if (ecCurve != null) { 817 s.append("\nEC Curve: ").append(ecCurveAsString()); 818 } 819 820 String label = "\nRSA exponent: "; 821 if (rsaPublicExponent != null) { 822 s.append(label).append(rsaPublicExponent); 823 } 824 825 if (mRsaOaepMgfDigests != null && !mRsaOaepMgfDigests.isEmpty()) { 826 s.append("\nRSA OAEP MGF Digests: ").append(digestsToString(mRsaOaepMgfDigests)); 827 } 828 829 if (activeDateTime != null) { 830 s.append("\nActive: ").append(formatDate(activeDateTime)); 831 } 832 833 if (originationExpireDateTime != null) { 834 s.append("\nOrigination expire: ").append(formatDate(originationExpireDateTime)); 835 } 836 837 if (usageExpireDateTime != null) { 838 s.append("\nUsage expire: ").append(formatDate(usageExpireDateTime)); 839 } 840 841 if (!noAuthRequired && userAuthType != null) { 842 s.append("\nAuth types: ").append(userAuthTypeToString(userAuthType)); 843 if (authTimeout != null) { 844 s.append("\nAuth timeout: ").append(authTimeout); 845 } 846 } 847 848 if (applicationId != null) { 849 s.append("\nApplication ID: ").append(new String(applicationId)); 850 } 851 852 if (creationDateTime != null) { 853 s.append("\nCreated: ").append(formatDate(creationDateTime)); 854 } 855 856 if (origin != null) { 857 s.append("\nOrigin: ").append(originToString(origin)); 858 } 859 860 if (rollbackResistant) { 861 s.append("\nRollback resistant: true"); 862 } 863 864 if (rollbackResistance) { 865 s.append("\nRollback resistance: true"); 866 } 867 868 if (rootOfTrust != null) { 869 s.append("\nRoot of Trust:\n"); 870 s.append(rootOfTrust); 871 } 872 873 if (osVersion != null) { 874 s.append("\nOS Version: ").append(osVersion); 875 } 876 877 if (osPatchLevel != null) { 878 s.append("\nOS Patchlevel: ").append(osPatchLevel); 879 } 880 881 if (vendorPatchLevel != null) { 882 s.append("\nVendor Patchlevel: ").append(vendorPatchLevel); 883 } 884 885 if (bootPatchLevel != null) { 886 s.append("\nBoot Patchlevel: ").append(bootPatchLevel); 887 } 888 889 if (attestationApplicationId != null) { 890 s.append("\nAttestation Application Id:").append(attestationApplicationId); 891 } 892 893 if (userPresenceRequired) { 894 s.append("\nUser presence required"); 895 } 896 897 if (confirmationRequired) { 898 s.append("\nConfirmation required"); 899 } 900 901 if (brand != null) { 902 s.append("\nBrand: ").append(brand); 903 } 904 if (device != null) { 905 s.append("\nDevice type: ").append(device); 906 } 907 return s.toString(); 908 } 909 } 910