1 package org.bouncycastle.jcajce.provider.asymmetric.x509; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.math.BigInteger; 6 import java.net.InetAddress; 7 import java.net.UnknownHostException; 8 import java.security.InvalidKeyException; 9 import java.security.NoSuchAlgorithmException; 10 import java.security.NoSuchProviderException; 11 import java.security.Principal; 12 import java.security.Provider; 13 import java.security.PublicKey; 14 import java.security.Signature; 15 import java.security.SignatureException; 16 import java.security.cert.CertificateEncodingException; 17 import java.security.cert.CertificateException; 18 import java.security.cert.CertificateExpiredException; 19 import java.security.cert.CertificateNotYetValidException; 20 import java.security.cert.CertificateParsingException; 21 import java.security.cert.X509Certificate; 22 import java.util.ArrayList; 23 import java.util.Collection; 24 import java.util.Collections; 25 import java.util.Date; 26 import java.util.Enumeration; 27 import java.util.HashSet; 28 import java.util.List; 29 import java.util.Set; 30 31 import javax.security.auth.x500.X500Principal; 32 33 import org.bouncycastle.asn1.ASN1BitString; 34 import org.bouncycastle.asn1.ASN1Encodable; 35 import org.bouncycastle.asn1.ASN1Encoding; 36 import org.bouncycastle.asn1.ASN1InputStream; 37 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 38 import org.bouncycastle.asn1.ASN1OutputStream; 39 import org.bouncycastle.asn1.ASN1Primitive; 40 import org.bouncycastle.asn1.ASN1Sequence; 41 import org.bouncycastle.asn1.ASN1String; 42 import org.bouncycastle.asn1.DERBitString; 43 import org.bouncycastle.asn1.DERIA5String; 44 import org.bouncycastle.asn1.DERNull; 45 import org.bouncycastle.asn1.DEROctetString; 46 import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; 47 import org.bouncycastle.asn1.misc.NetscapeCertType; 48 import org.bouncycastle.asn1.misc.NetscapeRevocationURL; 49 import org.bouncycastle.asn1.misc.VerisignCzagExtension; 50 import org.bouncycastle.asn1.util.ASN1Dump; 51 import org.bouncycastle.asn1.x500.X500Name; 52 import org.bouncycastle.asn1.x500.style.RFC4519Style; 53 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 54 import org.bouncycastle.asn1.x509.BasicConstraints; 55 import org.bouncycastle.asn1.x509.Extension; 56 import org.bouncycastle.asn1.x509.Extensions; 57 import org.bouncycastle.asn1.x509.GeneralName; 58 import org.bouncycastle.asn1.x509.KeyUsage; 59 // BEGIN Android-added: Unknown reason 60 import org.bouncycastle.asn1.x509.X509Name; 61 // END Android-added: Unknown reason 62 import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; 63 import org.bouncycastle.jcajce.util.JcaJceHelper; 64 import org.bouncycastle.jce.X509Principal; 65 import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; 66 import org.bouncycastle.jce.provider.BouncyCastleProvider; 67 import org.bouncycastle.util.Integers; 68 import org.bouncycastle.util.Strings; 69 import org.bouncycastle.util.encoders.Hex; 70 71 class X509CertificateObject 72 extends X509Certificate 73 implements PKCS12BagAttributeCarrier 74 { 75 private JcaJceHelper bcHelper; 76 private org.bouncycastle.asn1.x509.Certificate c; 77 private BasicConstraints basicConstraints; 78 private boolean[] keyUsage; 79 private boolean hashValueSet; 80 private int hashValue; 81 82 private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); 83 84 public X509CertificateObject( 85 JcaJceHelper bcHelper, 86 org.bouncycastle.asn1.x509.Certificate c) 87 throws CertificateParsingException 88 { 89 this.bcHelper = bcHelper; 90 this.c = c; 91 92 try 93 { 94 byte[] bytes = this.getExtensionBytes("2.5.29.19"); 95 96 if (bytes != null) 97 { 98 basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes)); 99 } 100 } 101 catch (Exception e) 102 { 103 throw new CertificateParsingException("cannot construct BasicConstraints: " + e); 104 } 105 106 try 107 { 108 byte[] bytes = this.getExtensionBytes("2.5.29.15"); 109 if (bytes != null) 110 { 111 ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); 112 113 bytes = bits.getBytes(); 114 int length = (bytes.length * 8) - bits.getPadBits(); 115 116 keyUsage = new boolean[(length < 9) ? 9 : length]; 117 118 for (int i = 0; i != length; i++) 119 { 120 keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; 121 } 122 } 123 else 124 { 125 keyUsage = null; 126 } 127 } 128 catch (Exception e) 129 { 130 throw new CertificateParsingException("cannot construct KeyUsage: " + e); 131 } 132 } 133 134 public void checkValidity() 135 throws CertificateExpiredException, CertificateNotYetValidException 136 { 137 this.checkValidity(new Date()); 138 } 139 140 public void checkValidity( 141 Date date) 142 throws CertificateExpiredException, CertificateNotYetValidException 143 { 144 if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility 145 { 146 throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime()); 147 } 148 149 if (date.getTime() < this.getNotBefore().getTime()) 150 { 151 throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime()); 152 } 153 } 154 155 public int getVersion() 156 { 157 return c.getVersionNumber(); 158 } 159 160 public BigInteger getSerialNumber() 161 { 162 return c.getSerialNumber().getValue(); 163 } 164 165 public Principal getIssuerDN() 166 { 167 try 168 { 169 return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded())); 170 } 171 catch (IOException e) 172 { 173 return null; 174 } 175 } 176 177 public X500Principal getIssuerX500Principal() 178 { 179 try 180 { 181 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 182 ASN1OutputStream aOut = new ASN1OutputStream(bOut); 183 184 aOut.writeObject(c.getIssuer()); 185 186 return new X500Principal(bOut.toByteArray()); 187 } 188 catch (IOException e) 189 { 190 throw new IllegalStateException("can't encode issuer DN"); 191 } 192 } 193 194 public Principal getSubjectDN() 195 { 196 return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive())); 197 } 198 199 public X500Principal getSubjectX500Principal() 200 { 201 try 202 { 203 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 204 ASN1OutputStream aOut = new ASN1OutputStream(bOut); 205 206 aOut.writeObject(c.getSubject()); 207 208 return new X500Principal(bOut.toByteArray()); 209 } 210 catch (IOException e) 211 { 212 throw new IllegalStateException("can't encode issuer DN"); 213 } 214 } 215 216 public Date getNotBefore() 217 { 218 return c.getStartDate().getDate(); 219 } 220 221 public Date getNotAfter() 222 { 223 return c.getEndDate().getDate(); 224 } 225 226 public byte[] getTBSCertificate() 227 throws CertificateEncodingException 228 { 229 try 230 { 231 return c.getTBSCertificate().getEncoded(ASN1Encoding.DER); 232 } 233 catch (IOException e) 234 { 235 throw new CertificateEncodingException(e.toString()); 236 } 237 } 238 239 public byte[] getSignature() 240 { 241 return c.getSignature().getOctets(); 242 } 243 244 /** 245 * return a more "meaningful" representation for the signature algorithm used in 246 * the certificate. 247 */ 248 public String getSigAlgName() 249 { 250 return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); 251 } 252 253 /** 254 * return the object identifier for the signature. 255 */ 256 public String getSigAlgOID() 257 { 258 return c.getSignatureAlgorithm().getAlgorithm().getId(); 259 } 260 261 /** 262 * return the signature parameters, or null if there aren't any. 263 */ 264 public byte[] getSigAlgParams() 265 { 266 if (c.getSignatureAlgorithm().getParameters() != null) 267 { 268 try 269 { 270 return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER); 271 } 272 catch (IOException e) 273 { 274 return null; 275 } 276 } 277 else 278 { 279 return null; 280 } 281 } 282 283 public boolean[] getIssuerUniqueID() 284 { 285 DERBitString id = c.getTBSCertificate().getIssuerUniqueId(); 286 287 if (id != null) 288 { 289 byte[] bytes = id.getBytes(); 290 boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; 291 292 for (int i = 0; i != boolId.length; i++) 293 { 294 boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; 295 } 296 297 return boolId; 298 } 299 300 return null; 301 } 302 303 public boolean[] getSubjectUniqueID() 304 { 305 DERBitString id = c.getTBSCertificate().getSubjectUniqueId(); 306 307 if (id != null) 308 { 309 byte[] bytes = id.getBytes(); 310 boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()]; 311 312 for (int i = 0; i != boolId.length; i++) 313 { 314 boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; 315 } 316 317 return boolId; 318 } 319 320 return null; 321 } 322 323 public boolean[] getKeyUsage() 324 { 325 return keyUsage; 326 } 327 328 public List getExtendedKeyUsage() 329 throws CertificateParsingException 330 { 331 byte[] bytes = this.getExtensionBytes("2.5.29.37"); 332 333 if (bytes != null) 334 { 335 try 336 { 337 ASN1InputStream dIn = new ASN1InputStream(bytes); 338 ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); 339 List list = new ArrayList(); 340 341 for (int i = 0; i != seq.size(); i++) 342 { 343 list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId()); 344 } 345 346 return Collections.unmodifiableList(list); 347 } 348 catch (Exception e) 349 { 350 throw new CertificateParsingException("error processing extended key usage extension"); 351 } 352 } 353 354 return null; 355 } 356 357 public int getBasicConstraints() 358 { 359 if (basicConstraints != null) 360 { 361 if (basicConstraints.isCA()) 362 { 363 if (basicConstraints.getPathLenConstraint() == null) 364 { 365 return Integer.MAX_VALUE; 366 } 367 else 368 { 369 return basicConstraints.getPathLenConstraint().intValue(); 370 } 371 } 372 else 373 { 374 return -1; 375 } 376 } 377 378 return -1; 379 } 380 381 public Collection getSubjectAlternativeNames() 382 throws CertificateParsingException 383 { 384 return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId())); 385 } 386 387 public Collection getIssuerAlternativeNames() 388 throws CertificateParsingException 389 { 390 return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId())); 391 } 392 393 public Set getCriticalExtensionOIDs() 394 { 395 if (this.getVersion() == 3) 396 { 397 Set set = new HashSet(); 398 Extensions extensions = c.getTBSCertificate().getExtensions(); 399 400 if (extensions != null) 401 { 402 Enumeration e = extensions.oids(); 403 404 while (e.hasMoreElements()) 405 { 406 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 407 Extension ext = extensions.getExtension(oid); 408 409 if (ext.isCritical()) 410 { 411 set.add(oid.getId()); 412 } 413 } 414 415 return set; 416 } 417 } 418 419 return null; 420 } 421 422 private byte[] getExtensionBytes(String oid) 423 { 424 Extensions exts = c.getTBSCertificate().getExtensions(); 425 426 if (exts != null) 427 { 428 Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); 429 if (ext != null) 430 { 431 return ext.getExtnValue().getOctets(); 432 } 433 } 434 435 return null; 436 } 437 438 public byte[] getExtensionValue(String oid) 439 { 440 Extensions exts = c.getTBSCertificate().getExtensions(); 441 442 if (exts != null) 443 { 444 Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); 445 446 if (ext != null) 447 { 448 try 449 { 450 return ext.getExtnValue().getEncoded(); 451 } 452 catch (Exception e) 453 { 454 throw new IllegalStateException("error parsing " + e.toString()); 455 } 456 } 457 } 458 459 return null; 460 } 461 462 public Set getNonCriticalExtensionOIDs() 463 { 464 if (this.getVersion() == 3) 465 { 466 Set set = new HashSet(); 467 Extensions extensions = c.getTBSCertificate().getExtensions(); 468 469 if (extensions != null) 470 { 471 Enumeration e = extensions.oids(); 472 473 while (e.hasMoreElements()) 474 { 475 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 476 Extension ext = extensions.getExtension(oid); 477 478 if (!ext.isCritical()) 479 { 480 set.add(oid.getId()); 481 } 482 } 483 484 return set; 485 } 486 } 487 488 return null; 489 } 490 491 public boolean hasUnsupportedCriticalExtension() 492 { 493 if (this.getVersion() == 3) 494 { 495 Extensions extensions = c.getTBSCertificate().getExtensions(); 496 497 if (extensions != null) 498 { 499 Enumeration e = extensions.oids(); 500 501 while (e.hasMoreElements()) 502 { 503 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 504 505 if (oid.equals(Extension.keyUsage) 506 || oid.equals(Extension.certificatePolicies) 507 || oid.equals(Extension.policyMappings) 508 || oid.equals(Extension.inhibitAnyPolicy) 509 || oid.equals(Extension.cRLDistributionPoints) 510 || oid.equals(Extension.issuingDistributionPoint) 511 || oid.equals(Extension.deltaCRLIndicator) 512 || oid.equals(Extension.policyConstraints) 513 || oid.equals(Extension.basicConstraints) 514 || oid.equals(Extension.subjectAlternativeName) 515 || oid.equals(Extension.nameConstraints)) 516 { 517 continue; 518 } 519 520 Extension ext = extensions.getExtension(oid); 521 522 if (ext.isCritical()) 523 { 524 return true; 525 } 526 } 527 } 528 } 529 530 return false; 531 } 532 533 public PublicKey getPublicKey() 534 { 535 try 536 { 537 return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo()); 538 } 539 catch (IOException e) 540 { 541 return null; // should never happen... 542 } 543 } 544 545 // Android-added: Cache the encoded certificate 546 private byte[] encoded; 547 public byte[] getEncoded() 548 throws CertificateEncodingException 549 { 550 try 551 { 552 // BEGIN Android-changed: Cache the encoded certificate 553 if (encoded == null) { 554 encoded = c.getEncoded(ASN1Encoding.DER); 555 } 556 return encoded; 557 // END Android-changed: Cache the encoded certificate 558 } 559 catch (IOException e) 560 { 561 throw new CertificateEncodingException(e.toString()); 562 } 563 } 564 565 public boolean equals( 566 Object o) 567 { 568 if (o == this) 569 { 570 return true; 571 } 572 573 if (o instanceof X509CertificateObject) 574 { 575 X509CertificateObject other = (X509CertificateObject)o; 576 577 if (this.hashValueSet && other.hashValueSet) 578 { 579 if (this.hashValue != other.hashValue) 580 { 581 return false; 582 } 583 } 584 585 return this.c.equals(other.c); 586 } 587 588 return super.equals(o); 589 } 590 591 public synchronized int hashCode() 592 { 593 if (!hashValueSet) 594 { 595 hashValue = super.hashCode(); 596 hashValueSet = true; 597 } 598 599 return hashValue; 600 } 601 602 /** 603 * Returns the original hash code for Certificates pre-JDK 1.8. 604 * 605 * @return the pre-JDK 1.8 hashcode calculation. 606 */ 607 public int originalHashCode() 608 { 609 try 610 { 611 int hashCode = 0; 612 byte[] certData = this.getEncoded(); 613 for (int i = 1; i < certData.length; i++) 614 { 615 hashCode += certData[i] * i; 616 } 617 return hashCode; 618 } 619 catch (CertificateEncodingException e) 620 { 621 return 0; 622 } 623 } 624 625 public void setBagAttribute( 626 ASN1ObjectIdentifier oid, 627 ASN1Encodable attribute) 628 { 629 attrCarrier.setBagAttribute(oid, attribute); 630 } 631 632 public ASN1Encodable getBagAttribute( 633 ASN1ObjectIdentifier oid) 634 { 635 return attrCarrier.getBagAttribute(oid); 636 } 637 638 public Enumeration getBagAttributeKeys() 639 { 640 return attrCarrier.getBagAttributeKeys(); 641 } 642 643 public String toString() 644 { 645 StringBuffer buf = new StringBuffer(); 646 String nl = Strings.lineSeparator(); 647 648 buf.append(" [0] Version: ").append(this.getVersion()).append(nl); 649 buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl); 650 buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl); 651 buf.append(" Start Date: ").append(this.getNotBefore()).append(nl); 652 buf.append(" Final Date: ").append(this.getNotAfter()).append(nl); 653 buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl); 654 buf.append(" Public Key: ").append(this.getPublicKey()).append(nl); 655 buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl); 656 657 byte[] sig = this.getSignature(); 658 659 buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl); 660 for (int i = 20; i < sig.length; i += 20) 661 { 662 if (i < sig.length - 20) 663 { 664 buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl); 665 } 666 else 667 { 668 buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl); 669 } 670 } 671 672 Extensions extensions = c.getTBSCertificate().getExtensions(); 673 674 if (extensions != null) 675 { 676 Enumeration e = extensions.oids(); 677 678 if (e.hasMoreElements()) 679 { 680 buf.append(" Extensions: \n"); 681 } 682 683 while (e.hasMoreElements()) 684 { 685 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 686 Extension ext = extensions.getExtension(oid); 687 688 if (ext.getExtnValue() != null) 689 { 690 byte[] octs = ext.getExtnValue().getOctets(); 691 ASN1InputStream dIn = new ASN1InputStream(octs); 692 buf.append(" critical(").append(ext.isCritical()).append(") "); 693 try 694 { 695 if (oid.equals(Extension.basicConstraints)) 696 { 697 buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl); 698 } 699 else if (oid.equals(Extension.keyUsage)) 700 { 701 buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl); 702 } 703 else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) 704 { 705 buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl); 706 } 707 else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) 708 { 709 buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl); 710 } 711 else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) 712 { 713 buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl); 714 } 715 else 716 { 717 buf.append(oid.getId()); 718 buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); 719 //buf.append(" value = ").append("*****").append(nl); 720 } 721 } 722 catch (Exception ex) 723 { 724 buf.append(oid.getId()); 725 // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); 726 buf.append(" value = ").append("*****").append(nl); 727 } 728 } 729 else 730 { 731 buf.append(nl); 732 } 733 } 734 } 735 736 return buf.toString(); 737 } 738 739 public final void verify( 740 PublicKey key) 741 throws CertificateException, NoSuchAlgorithmException, 742 InvalidKeyException, NoSuchProviderException, SignatureException 743 { 744 Signature signature; 745 String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); 746 747 try 748 { 749 signature = bcHelper.createSignature(sigName); 750 } 751 catch (Exception e) 752 { 753 signature = Signature.getInstance(sigName); 754 } 755 756 checkSignature(key, signature); 757 } 758 759 public final void verify( 760 PublicKey key, 761 String sigProvider) 762 throws CertificateException, NoSuchAlgorithmException, 763 InvalidKeyException, NoSuchProviderException, SignatureException 764 { 765 String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); 766 Signature signature; 767 768 if (sigProvider != null) 769 { 770 signature = Signature.getInstance(sigName, sigProvider); 771 } 772 else 773 { 774 signature = Signature.getInstance(sigName); 775 } 776 777 checkSignature(key, signature); 778 } 779 780 public final void verify( 781 PublicKey key, 782 Provider sigProvider) 783 throws CertificateException, NoSuchAlgorithmException, 784 InvalidKeyException, SignatureException 785 { 786 String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); 787 Signature signature; 788 789 if (sigProvider != null) 790 { 791 signature = Signature.getInstance(sigName, sigProvider); 792 } 793 else 794 { 795 signature = Signature.getInstance(sigName); 796 } 797 798 checkSignature(key, signature); 799 } 800 801 private void checkSignature( 802 PublicKey key, 803 Signature signature) 804 throws CertificateException, NoSuchAlgorithmException, 805 SignatureException, InvalidKeyException 806 { 807 if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature())) 808 { 809 throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); 810 } 811 812 ASN1Encodable params = c.getSignatureAlgorithm().getParameters(); 813 814 // TODO This should go after the initVerify? 815 X509SignatureUtil.setSignatureParameters(signature, params); 816 817 signature.initVerify(key); 818 819 signature.update(this.getTBSCertificate()); 820 821 if (!signature.verify(this.getSignature())) 822 { 823 throw new SignatureException("certificate does not verify with supplied key"); 824 } 825 } 826 827 private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) 828 { 829 if (!id1.getAlgorithm().equals(id2.getAlgorithm())) 830 { 831 return false; 832 } 833 834 if (id1.getParameters() == null) 835 { 836 if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) 837 { 838 return false; 839 } 840 841 return true; 842 } 843 844 if (id2.getParameters() == null) 845 { 846 if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) 847 { 848 return false; 849 } 850 851 return true; 852 } 853 854 return id1.getParameters().equals(id2.getParameters()); 855 } 856 857 private static Collection getAlternativeNames(byte[] extVal) 858 throws CertificateParsingException 859 { 860 if (extVal == null) 861 { 862 return null; 863 } 864 try 865 { 866 Collection temp = new ArrayList(); 867 Enumeration it = ASN1Sequence.getInstance(extVal).getObjects(); 868 while (it.hasMoreElements()) 869 { 870 GeneralName genName = GeneralName.getInstance(it.nextElement()); 871 List list = new ArrayList(); 872 list.add(Integers.valueOf(genName.getTagNo())); 873 switch (genName.getTagNo()) 874 { 875 case GeneralName.ediPartyName: 876 case GeneralName.x400Address: 877 case GeneralName.otherName: 878 list.add(genName.getEncoded()); 879 break; 880 case GeneralName.directoryName: 881 // Android-changed: Unknown reason 882 // list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString()); 883 list.add(X509Name.getInstance(genName.getName()).toString(true, X509Name.DefaultSymbols)); 884 break; 885 case GeneralName.dNSName: 886 case GeneralName.rfc822Name: 887 case GeneralName.uniformResourceIdentifier: 888 list.add(((ASN1String)genName.getName()).getString()); 889 break; 890 case GeneralName.registeredID: 891 list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId()); 892 break; 893 case GeneralName.iPAddress: 894 byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets(); 895 final String addr; 896 try 897 { 898 addr = InetAddress.getByAddress(addrBytes).getHostAddress(); 899 } 900 catch (UnknownHostException e) 901 { 902 continue; 903 } 904 list.add(addr); 905 break; 906 default: 907 throw new IOException("Bad tag number: " + genName.getTagNo()); 908 } 909 910 temp.add(Collections.unmodifiableList(list)); 911 } 912 if (temp.size() == 0) 913 { 914 return null; 915 } 916 return Collections.unmodifiableCollection(temp); 917 } 918 catch (Exception e) 919 { 920 throw new CertificateParsingException(e.getMessage()); 921 } 922 } 923 } 924