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