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 com.google.common.base.Joiner; 23 import com.google.common.collect.ImmutableMap; 24 import com.google.common.collect.ImmutableSet; 25 import com.google.common.collect.Lists; 26 27 import android.security.keystore.KeyProperties; 28 import android.util.Log; 29 30 import com.android.org.bouncycastle.asn1.ASN1Encodable; 31 import com.android.org.bouncycastle.asn1.ASN1Primitive; 32 import com.android.org.bouncycastle.asn1.ASN1Sequence; 33 import com.android.org.bouncycastle.asn1.ASN1SequenceParser; 34 import com.android.org.bouncycastle.asn1.ASN1TaggedObject; 35 import com.android.org.bouncycastle.asn1.ASN1InputStream; 36 37 import java.io.IOException; 38 import java.io.UnsupportedEncodingException; 39 import java.security.cert.CertificateParsingException; 40 import java.text.DateFormat; 41 import java.util.Collection; 42 import java.util.Date; 43 import java.util.List; 44 import java.util.Set; 45 46 public class AuthorizationList { 47 // Algorithm values. 48 public static final int KM_ALGORITHM_RSA = 1; 49 public static final int KM_ALGORITHM_EC = 3; 50 51 // EC Curves 52 public static final int KM_EC_CURVE_P224 = 0; 53 public static final int KM_EC_CURVE_P256 = 1; 54 public static final int KM_EC_CURVE_P384 = 2; 55 public static final int KM_EC_CURVE_P521 = 3; 56 57 // Padding modes. 58 public static final int KM_PAD_NONE = 1; 59 public static final int KM_PAD_RSA_OAEP = 2; 60 public static final int KM_PAD_RSA_PSS = 3; 61 public static final int KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4; 62 public static final int KM_PAD_RSA_PKCS1_1_5_SIGN = 5; 63 64 // Digest modes. 65 public static final int KM_DIGEST_NONE = 0; 66 public static final int KM_DIGEST_MD5 = 1; 67 public static final int KM_DIGEST_SHA1 = 2; 68 public static final int KM_DIGEST_SHA_2_224 = 3; 69 public static final int KM_DIGEST_SHA_2_256 = 4; 70 public static final int KM_DIGEST_SHA_2_384 = 5; 71 public static final int KM_DIGEST_SHA_2_512 = 6; 72 73 // Key origins. 74 public static final int KM_ORIGIN_GENERATED = 0; 75 public static final int KM_ORIGIN_IMPORTED = 2; 76 public static final int KM_ORIGIN_UNKNOWN = 3; 77 78 // Operation Purposes. 79 public static final int KM_PURPOSE_ENCRYPT = 0; 80 public static final int KM_PURPOSE_DECRYPT = 1; 81 public static final int KM_PURPOSE_SIGN = 2; 82 public static final int KM_PURPOSE_VERIFY = 3; 83 84 // User authenticators. 85 public static final int HW_AUTH_PASSWORD = 1 << 0; 86 public static final int HW_AUTH_FINGERPRINT = 1 << 1; 87 88 // Keymaster tag classes 89 private static final int KM_ENUM = 1 << 28; 90 private static final int KM_ENUM_REP = 2 << 28; 91 private static final int KM_UINT = 3 << 28; 92 private static final int KM_ULONG = 5 << 28; 93 private static final int KM_DATE = 6 << 28; 94 private static final int KM_BOOL = 7 << 28; 95 private static final int KM_BYTES = 9 << 28; 96 97 // Tag class removal mask 98 private static final int KEYMASTER_TAG_TYPE_MASK = 0x0FFFFFFF; 99 100 // Keymaster tags 101 private static final int KM_TAG_PURPOSE = KM_ENUM_REP | 1; 102 private static final int KM_TAG_ALGORITHM = KM_ENUM | 2; 103 private static final int KM_TAG_KEY_SIZE = KM_UINT | 3; 104 private static final int KM_TAG_DIGEST = KM_ENUM_REP | 5; 105 private static final int KM_TAG_PADDING = KM_ENUM_REP | 6; 106 private static final int KM_TAG_EC_CURVE = KM_ENUM | 10; 107 private static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_ULONG | 200; 108 private static final int KM_TAG_ACTIVE_DATETIME = KM_DATE | 400; 109 private static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401; 110 private static final int KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402; 111 private static final int KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503; 112 private static final int KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504; 113 private static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506; 114 private static final int KM_TAG_AUTH_TIMEOUT = KM_UINT | 505; 115 private static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600; 116 private static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601; 117 private static final int KM_TAG_CREATION_DATETIME = KM_DATE | 701; 118 private static final int KM_TAG_ORIGIN = KM_ENUM | 702; 119 private static final int KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703; 120 private static final int KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704; 121 private static final int KM_TAG_OS_VERSION = KM_UINT | 705; 122 private static final int KM_TAG_OS_PATCHLEVEL = KM_UINT | 706; 123 private static final int KM_TAG_ATTESTATION_APPLICATION_ID = KM_BYTES | 709; 124 private static final int KM_TAG_ATTESTATION_ID_BRAND = KM_BYTES | 710; 125 private static final int KM_TAG_ATTESTATION_ID_DEVICE = KM_BYTES | 711; 126 private static final int KM_TAG_ATTESTATION_ID_PRODUCT = KM_BYTES | 712; 127 private static final int KM_TAG_ATTESTATION_ID_SERIAL = KM_BYTES | 713; 128 private static final int KM_TAG_ATTESTATION_ID_IMEI = KM_BYTES | 714; 129 private static final int KM_TAG_ATTESTATION_ID_MEID = KM_BYTES | 715; 130 private static final int KM_TAG_ATTESTATION_ID_MANUFACTURER = KM_BYTES | 716; 131 private static final int KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717; 132 133 // Map for converting padding values to strings 134 private static final ImmutableMap<Integer, String> paddingMap = ImmutableMap 135 .<Integer, String> builder() 136 .put(KM_PAD_NONE, "NONE") 137 .put(KM_PAD_RSA_OAEP, "OAEP") 138 .put(KM_PAD_RSA_PSS, "PSS") 139 .put(KM_PAD_RSA_PKCS1_1_5_ENCRYPT, "PKCS1 ENCRYPT") 140 .put(KM_PAD_RSA_PKCS1_1_5_SIGN, "PKCS1 SIGN") 141 .build(); 142 143 // Map for converting digest values to strings 144 private static final ImmutableMap<Integer, String> digestMap = ImmutableMap 145 .<Integer, String> builder() 146 .put(KM_DIGEST_NONE, "NONE") 147 .put(KM_DIGEST_MD5, "MD5") 148 .put(KM_DIGEST_SHA1, "SHA1") 149 .put(KM_DIGEST_SHA_2_224, "SHA224") 150 .put(KM_DIGEST_SHA_2_256, "SHA256") 151 .put(KM_DIGEST_SHA_2_384, "SHA384") 152 .put(KM_DIGEST_SHA_2_512, "SHA512") 153 .build(); 154 155 // Map for converting purpose values to strings 156 private static final ImmutableMap<Integer, String> purposeMap = ImmutableMap 157 .<Integer, String> builder() 158 .put(KM_PURPOSE_DECRYPT, "DECRYPT") 159 .put(KM_PURPOSE_ENCRYPT, "ENCRYPT") 160 .put(KM_PURPOSE_SIGN, "SIGN") 161 .put(KM_PURPOSE_VERIFY, "VERIFY") 162 .build(); 163 164 private Set<Integer> purposes; 165 private Integer algorithm; 166 private Integer keySize; 167 private Set<Integer> digests; 168 private Set<Integer> paddingModes; 169 private Integer ecCurve; 170 private Long rsaPublicExponent; 171 private Date activeDateTime; 172 private Date originationExpireDateTime; 173 private Date usageExpireDateTime; 174 private boolean noAuthRequired; 175 private Integer userAuthType; 176 private Integer authTimeout; 177 private boolean allowWhileOnBody; 178 private boolean allApplications; 179 private byte[] applicationId; 180 private Date creationDateTime; 181 private Integer origin; 182 private boolean rollbackResistant; 183 private RootOfTrust rootOfTrust; 184 private Integer osVersion; 185 private Integer osPatchLevel; 186 private AttestationApplicationId attestationApplicationId; 187 private String brand; 188 private String device; 189 private String serialNumber; 190 private String imei; 191 private String meid; 192 private String product; 193 private String manufacturer; 194 private String model; 195 AuthorizationList(ASN1Encodable sequence)196 public AuthorizationList(ASN1Encodable sequence) throws CertificateParsingException { 197 if (!(sequence instanceof ASN1Sequence)) { 198 throw new CertificateParsingException("Expected sequence for authorization list, found " 199 + sequence.getClass().getName()); 200 } 201 202 ASN1SequenceParser parser = ((ASN1Sequence) sequence).parser(); 203 ASN1TaggedObject entry = parseAsn1TaggedObject(parser); 204 for (; entry != null; entry = parseAsn1TaggedObject(parser)) { 205 int tag = entry.getTagNo(); 206 ASN1Primitive value = entry.getObject(); 207 Log.i("Attestation", "Parsing tag: [" + tag + "], value: [" + value + "]"); 208 switch (tag) { 209 default: 210 throw new CertificateParsingException("Unknown tag " + tag + " found"); 211 212 case KM_TAG_PURPOSE & KEYMASTER_TAG_TYPE_MASK: 213 purposes = Asn1Utils.getIntegersFromAsn1Set(value); 214 break; 215 case KM_TAG_ALGORITHM & KEYMASTER_TAG_TYPE_MASK: 216 algorithm = Asn1Utils.getIntegerFromAsn1(value); 217 break; 218 case KM_TAG_KEY_SIZE & KEYMASTER_TAG_TYPE_MASK: 219 keySize = Asn1Utils.getIntegerFromAsn1(value); 220 Log.i("Attestation", "Found KEY SIZE, value: " + keySize); 221 break; 222 case KM_TAG_DIGEST & KEYMASTER_TAG_TYPE_MASK: 223 digests = Asn1Utils.getIntegersFromAsn1Set(value); 224 break; 225 case KM_TAG_PADDING & KEYMASTER_TAG_TYPE_MASK: 226 paddingModes = Asn1Utils.getIntegersFromAsn1Set(value); 227 break; 228 case KM_TAG_RSA_PUBLIC_EXPONENT & KEYMASTER_TAG_TYPE_MASK: 229 rsaPublicExponent = Asn1Utils.getLongFromAsn1(value); 230 break; 231 case KM_TAG_NO_AUTH_REQUIRED & KEYMASTER_TAG_TYPE_MASK: 232 noAuthRequired = true; 233 break; 234 case KM_TAG_CREATION_DATETIME & KEYMASTER_TAG_TYPE_MASK: 235 creationDateTime = Asn1Utils.getDateFromAsn1(value); 236 break; 237 case KM_TAG_ORIGIN & KEYMASTER_TAG_TYPE_MASK: 238 origin = Asn1Utils.getIntegerFromAsn1(value); 239 break; 240 case KM_TAG_OS_VERSION & KEYMASTER_TAG_TYPE_MASK: 241 osVersion = Asn1Utils.getIntegerFromAsn1(value); 242 break; 243 case KM_TAG_OS_PATCHLEVEL & KEYMASTER_TAG_TYPE_MASK: 244 osPatchLevel = Asn1Utils.getIntegerFromAsn1(value); 245 break; 246 case KM_TAG_ACTIVE_DATETIME & KEYMASTER_TAG_TYPE_MASK: 247 activeDateTime = Asn1Utils.getDateFromAsn1(value); 248 break; 249 case KM_TAG_ORIGINATION_EXPIRE_DATETIME & KEYMASTER_TAG_TYPE_MASK: 250 originationExpireDateTime = Asn1Utils.getDateFromAsn1(value); 251 break; 252 case KM_TAG_USAGE_EXPIRE_DATETIME & KEYMASTER_TAG_TYPE_MASK: 253 usageExpireDateTime = Asn1Utils.getDateFromAsn1(value); 254 break; 255 case KM_TAG_APPLICATION_ID & KEYMASTER_TAG_TYPE_MASK: 256 applicationId = Asn1Utils.getByteArrayFromAsn1(value); 257 break; 258 case KM_TAG_ROLLBACK_RESISTANT & KEYMASTER_TAG_TYPE_MASK: 259 rollbackResistant = true; 260 break; 261 case KM_TAG_AUTH_TIMEOUT & KEYMASTER_TAG_TYPE_MASK: 262 authTimeout = Asn1Utils.getIntegerFromAsn1(value); 263 break; 264 case KM_TAG_ALLOW_WHILE_ON_BODY & KEYMASTER_TAG_TYPE_MASK: 265 allowWhileOnBody = true; 266 break; 267 case KM_TAG_EC_CURVE & KEYMASTER_TAG_TYPE_MASK: 268 ecCurve = Asn1Utils.getIntegerFromAsn1(value); 269 break; 270 case KM_TAG_USER_AUTH_TYPE & KEYMASTER_TAG_TYPE_MASK: 271 userAuthType = Asn1Utils.getIntegerFromAsn1(value); 272 break; 273 case KM_TAG_ROOT_OF_TRUST & KEYMASTER_TAG_TYPE_MASK: 274 rootOfTrust = new RootOfTrust(value); 275 break; 276 case KM_TAG_ATTESTATION_APPLICATION_ID & KEYMASTER_TAG_TYPE_MASK: 277 attestationApplicationId = new AttestationApplicationId(Asn1Utils 278 .getAsn1EncodableFromBytes(Asn1Utils.getByteArrayFromAsn1(value))); 279 break; 280 case KM_TAG_ATTESTATION_ID_BRAND & KEYMASTER_TAG_TYPE_MASK: 281 brand = getStringFromAsn1Value(value); 282 break; 283 case KM_TAG_ATTESTATION_ID_DEVICE & KEYMASTER_TAG_TYPE_MASK: 284 device = getStringFromAsn1Value(value); 285 break; 286 case KM_TAG_ATTESTATION_ID_PRODUCT & KEYMASTER_TAG_TYPE_MASK: 287 product = getStringFromAsn1Value(value); 288 break; 289 case KM_TAG_ATTESTATION_ID_SERIAL & KEYMASTER_TAG_TYPE_MASK: 290 serialNumber = getStringFromAsn1Value(value); 291 break; 292 case KM_TAG_ATTESTATION_ID_IMEI & KEYMASTER_TAG_TYPE_MASK: 293 imei = getStringFromAsn1Value(value); 294 break; 295 case KM_TAG_ATTESTATION_ID_MEID & KEYMASTER_TAG_TYPE_MASK: 296 meid = getStringFromAsn1Value(value); 297 break; 298 case KM_TAG_ATTESTATION_ID_MANUFACTURER & KEYMASTER_TAG_TYPE_MASK: 299 manufacturer = getStringFromAsn1Value(value); 300 break; 301 case KM_TAG_ATTESTATION_ID_MODEL & KEYMASTER_TAG_TYPE_MASK: 302 model = getStringFromAsn1Value(value); 303 break; 304 case KM_TAG_ALL_APPLICATIONS & KEYMASTER_TAG_TYPE_MASK: 305 allApplications = true; 306 break; 307 } 308 } 309 310 } 311 algorithmToString(int algorithm)312 public static String algorithmToString(int algorithm) { 313 switch (algorithm) { 314 case KM_ALGORITHM_RSA: 315 return "RSA"; 316 case KM_ALGORITHM_EC: 317 return "ECDSA"; 318 default: 319 return "Unknown"; 320 } 321 } 322 paddingModesToString(final Set<Integer> paddingModes)323 public static String paddingModesToString(final Set<Integer> paddingModes) { 324 return joinStrings(transform(paddingModes, forMap(paddingMap, "Unknown"))); 325 } 326 paddingModeToString(int paddingMode)327 public static String paddingModeToString(int paddingMode) { 328 return forMap(paddingMap, "Unknown").apply(paddingMode); 329 } 330 digestsToString(Set<Integer> digests)331 public static String digestsToString(Set<Integer> digests) { 332 return joinStrings(transform(digests, forMap(digestMap, "Unknown"))); 333 } 334 digestToString(int digest)335 public static String digestToString(int digest) { 336 return forMap(digestMap, "Unknown").apply(digest); 337 } 338 purposesToString(Set<Integer> purposes)339 public static String purposesToString(Set<Integer> purposes) { 340 return joinStrings(transform(purposes, forMap(purposeMap, "Unknown"))); 341 } 342 userAuthTypeToString(int userAuthType)343 public static String userAuthTypeToString(int userAuthType) { 344 List<String> types = Lists.newArrayList(); 345 if ((userAuthType & HW_AUTH_FINGERPRINT) != 0) 346 types.add("Fingerprint"); 347 if ((userAuthType & HW_AUTH_PASSWORD) != 0) 348 types.add("Password"); 349 return joinStrings(types); 350 } 351 originToString(int origin)352 public static String originToString(int origin) { 353 switch (origin) { 354 case KM_ORIGIN_GENERATED: 355 return "Generated"; 356 case KM_ORIGIN_IMPORTED: 357 return "Imported"; 358 case KM_ORIGIN_UNKNOWN: 359 return "Unknown (KM0)"; 360 default: 361 return "Unknown"; 362 } 363 } 364 joinStrings(Collection<String> collection)365 private static String joinStrings(Collection<String> collection) { 366 return new StringBuilder() 367 .append("[") 368 .append(Joiner.on(", ").join(collection)) 369 .append("]") 370 .toString(); 371 } 372 formatDate(Date date)373 private static String formatDate(Date date) { 374 return DateFormat.getDateTimeInstance().format(date); 375 } 376 parseAsn1TaggedObject(ASN1SequenceParser parser)377 private static ASN1TaggedObject parseAsn1TaggedObject(ASN1SequenceParser parser) 378 throws CertificateParsingException { 379 ASN1Encodable asn1Encodable = parseAsn1Encodable(parser); 380 if (asn1Encodable == null || asn1Encodable instanceof ASN1TaggedObject) { 381 return (ASN1TaggedObject) asn1Encodable; 382 } 383 throw new CertificateParsingException( 384 "Expected tagged object, found " + asn1Encodable.getClass().getName()); 385 } 386 parseAsn1Encodable(ASN1SequenceParser parser)387 private static ASN1Encodable parseAsn1Encodable(ASN1SequenceParser parser) 388 throws CertificateParsingException { 389 try { 390 return parser.readObject(); 391 } catch (IOException e) { 392 throw new CertificateParsingException("Failed to parse ASN1 sequence", e); 393 } 394 } 395 getPurposes()396 public Set<Integer> getPurposes() { 397 return purposes; 398 } 399 getAlgorithm()400 public Integer getAlgorithm() { 401 return algorithm; 402 } 403 getKeySize()404 public Integer getKeySize() { 405 return keySize; 406 } 407 getDigests()408 public Set<Integer> getDigests() { 409 return digests; 410 } 411 getPaddingModes()412 public Set<Integer> getPaddingModes() { 413 return paddingModes; 414 } 415 getPaddingModesAsStrings()416 public Set<String> getPaddingModesAsStrings() throws CertificateParsingException { 417 if (paddingModes == null) { 418 return ImmutableSet.of(); 419 } 420 421 ImmutableSet.Builder<String> builder = ImmutableSet.builder(); 422 for (int paddingMode : paddingModes) { 423 switch (paddingMode) { 424 case KM_PAD_NONE: 425 builder.add(KeyProperties.ENCRYPTION_PADDING_NONE); 426 break; 427 case KM_PAD_RSA_OAEP: 428 builder.add(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP); 429 break; 430 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT: 431 builder.add(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1); 432 break; 433 case KM_PAD_RSA_PKCS1_1_5_SIGN: 434 builder.add(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); 435 break; 436 case KM_PAD_RSA_PSS: 437 builder.add(KeyProperties.SIGNATURE_PADDING_RSA_PSS); 438 break; 439 default: 440 throw new CertificateParsingException("Invalid padding mode " + paddingMode); 441 } 442 } 443 return builder.build(); 444 } 445 getEcCurve()446 public Integer getEcCurve() { 447 return ecCurve; 448 } 449 ecCurveAsString()450 public String ecCurveAsString() { 451 if (ecCurve == null) 452 return "NULL"; 453 454 switch (ecCurve) { 455 case KM_EC_CURVE_P224: 456 return "secp224r1"; 457 case KM_EC_CURVE_P256: 458 return "secp256r1"; 459 case KM_EC_CURVE_P384: 460 return "secp384r1"; 461 case KM_EC_CURVE_P521: 462 return "secp521r1"; 463 default: 464 return "unknown"; 465 } 466 } 467 getRsaPublicExponent()468 public Long getRsaPublicExponent() { 469 return rsaPublicExponent; 470 } 471 getActiveDateTime()472 public Date getActiveDateTime() { 473 return activeDateTime; 474 } 475 getOriginationExpireDateTime()476 public Date getOriginationExpireDateTime() { 477 return originationExpireDateTime; 478 } 479 getUsageExpireDateTime()480 public Date getUsageExpireDateTime() { 481 return usageExpireDateTime; 482 } 483 isNoAuthRequired()484 public boolean isNoAuthRequired() { 485 return noAuthRequired; 486 } 487 getUserAuthType()488 public Integer getUserAuthType() { 489 return userAuthType; 490 } 491 getAuthTimeout()492 public Integer getAuthTimeout() { 493 return authTimeout; 494 } 495 isAllowWhileOnBody()496 public boolean isAllowWhileOnBody() { 497 return allowWhileOnBody; 498 } 499 isAllApplications()500 public boolean isAllApplications() { 501 return allApplications; 502 } 503 getApplicationId()504 public byte[] getApplicationId() { 505 return applicationId; 506 } 507 getCreationDateTime()508 public Date getCreationDateTime() { 509 return creationDateTime; 510 } 511 getOrigin()512 public Integer getOrigin() { 513 return origin; 514 } 515 isRollbackResistant()516 public boolean isRollbackResistant() { 517 return rollbackResistant; 518 } 519 getRootOfTrust()520 public RootOfTrust getRootOfTrust() { 521 return rootOfTrust; 522 } 523 getOsVersion()524 public Integer getOsVersion() { 525 return osVersion; 526 } 527 getOsPatchLevel()528 public Integer getOsPatchLevel() { 529 return osPatchLevel; 530 } 531 getAttestationApplicationId()532 public AttestationApplicationId getAttestationApplicationId() { 533 return attestationApplicationId; 534 } 535 getBrand()536 public String getBrand() { 537 return brand; 538 } 539 getDevice()540 public String getDevice() { 541 return device; 542 } 543 getSerialNumber()544 public String getSerialNumber() { 545 return serialNumber; 546 }; 547 getImei()548 public String getImei() { 549 return imei; 550 }; 551 getMeid()552 public String getMeid() { 553 return meid; 554 }; 555 getProduct()556 public String getProduct() { 557 return product; 558 }; 559 getManufacturer()560 public String getManufacturer() { 561 return manufacturer; 562 }; 563 getModel()564 public String getModel() { 565 return model; 566 }; 567 getStringFromAsn1Value(ASN1Primitive value)568 private String getStringFromAsn1Value(ASN1Primitive value) throws CertificateParsingException { 569 try { 570 return Asn1Utils.getStringFromAsn1OctetStreamAssumingUTF8(value); 571 } catch (UnsupportedEncodingException e) { 572 throw new CertificateParsingException("Error parsing ASN.1 value", e); 573 } 574 } 575 576 @Override toString()577 public String toString() { 578 StringBuilder s = new StringBuilder(); 579 580 if (algorithm != null) { 581 s.append("\nAlgorithm: ").append(algorithmToString(algorithm)); 582 } 583 584 if (keySize != null) { 585 s.append("\nKeySize: ").append(keySize); 586 } 587 588 if (purposes != null && !purposes.isEmpty()) { 589 s.append("\nPurposes: ").append(purposesToString(purposes)); 590 } 591 592 if (digests != null && !digests.isEmpty()) { 593 s.append("\nDigests: ").append(digestsToString(digests)); 594 } 595 596 if (paddingModes != null && !paddingModes.isEmpty()) { 597 s.append("\nPadding modes: ").append(paddingModesToString(paddingModes)); 598 } 599 600 if (ecCurve != null) { 601 s.append("\nEC Curve: ").append(ecCurveAsString()); 602 } 603 604 String label = "\nRSA exponent: "; 605 if (rsaPublicExponent != null) { 606 s.append(label).append(rsaPublicExponent); 607 } 608 609 if (activeDateTime != null) { 610 s.append("\nActive: ").append(formatDate(activeDateTime)); 611 } 612 613 if (originationExpireDateTime != null) { 614 s.append("\nOrigination expire: ").append(formatDate(originationExpireDateTime)); 615 } 616 617 if (usageExpireDateTime != null) { 618 s.append("\nUsage expire: ").append(formatDate(usageExpireDateTime)); 619 } 620 621 if (!noAuthRequired && userAuthType != null) { 622 s.append("\nAuth types: ").append(userAuthTypeToString(userAuthType)); 623 if (authTimeout != null) { 624 s.append("\nAuth timeout: ").append(authTimeout); 625 } 626 } 627 628 if (applicationId != null) { 629 s.append("\nApplication ID: ").append(new String(applicationId)); 630 } 631 632 if (creationDateTime != null) { 633 s.append("\nCreated: ").append(formatDate(creationDateTime)); 634 } 635 636 if (origin != null) { 637 s.append("\nOrigin: ").append(originToString(origin)); 638 } 639 640 if (rollbackResistant) { 641 s.append("\nRollback resistant: true"); 642 } 643 644 if (rootOfTrust != null) { 645 s.append("\nRoot of Trust:\n"); 646 s.append(rootOfTrust); 647 } 648 649 if (osVersion != null) { 650 s.append("\nOS Version: ").append(osVersion); 651 } 652 653 if (osPatchLevel != null) { 654 s.append("\nOS Patchlevel: ").append(osPatchLevel); 655 } 656 657 if (attestationApplicationId != null) { 658 s.append("\nAttestation Application Id:").append(attestationApplicationId); 659 } 660 661 if (brand != null) { 662 s.append("\nBrand: ").append(brand); 663 } 664 if (device != null) { 665 s.append("\nDevice type: ").append(device); 666 } 667 return s.toString(); 668 } 669 } 670