1 13 14 package org.ejbca.util; 15 16 import java.io.BufferedReader ; 17 import java.io.ByteArrayInputStream ; 18 import java.io.ByteArrayOutputStream ; 19 import java.io.FileInputStream ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.io.InputStreamReader ; 23 import java.io.PrintStream ; 24 import java.math.BigInteger ; 25 import java.net.URL ; 26 import java.security.InvalidKeyException ; 27 import java.security.MessageDigest ; 28 import java.security.NoSuchAlgorithmException ; 29 import java.security.NoSuchProviderException ; 30 import java.security.PrivateKey ; 31 import java.security.PublicKey ; 32 import java.security.SecureRandom ; 33 import java.security.Security ; 34 import java.security.SignatureException ; 35 import java.security.cert.CRLException ; 36 import java.security.cert.Certificate ; 37 import java.security.cert.CertificateEncodingException ; 38 import java.security.cert.CertificateException ; 39 import java.security.cert.CertificateFactory ; 40 import java.security.cert.CertificateParsingException ; 41 import java.security.cert.X509CRL ; 42 import java.security.cert.X509Certificate ; 43 import java.util.ArrayList ; 44 import java.util.Collection ; 45 import java.util.Date ; 46 import java.util.Hashtable ; 47 import java.util.Iterator ; 48 import java.util.List ; 49 import java.util.Vector ; 50 51 import org.apache.commons.lang.BooleanUtils; 52 import org.apache.commons.lang.StringUtils; 53 import org.apache.log4j.Logger; 54 import org.bouncycastle.asn1.ASN1EncodableVector; 55 import org.bouncycastle.asn1.ASN1InputStream; 56 import org.bouncycastle.asn1.ASN1OctetString; 57 import org.bouncycastle.asn1.ASN1Sequence; 58 import org.bouncycastle.asn1.ASN1TaggedObject; 59 import org.bouncycastle.asn1.DERBitString; 60 import org.bouncycastle.asn1.DEREncodable; 61 import org.bouncycastle.asn1.DERIA5String; 62 import org.bouncycastle.asn1.DERObject; 63 import org.bouncycastle.asn1.DERObjectIdentifier; 64 import org.bouncycastle.asn1.DEROctetString; 65 import org.bouncycastle.asn1.DERSequence; 66 import org.bouncycastle.asn1.DERTaggedObject; 67 import org.bouncycastle.asn1.DERUTF8String; 68 import org.bouncycastle.asn1.x509.AccessDescription; 69 import org.bouncycastle.asn1.x509.AuthorityInformationAccess; 70 import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; 71 import org.bouncycastle.asn1.x509.BasicConstraints; 72 import org.bouncycastle.asn1.x509.GeneralName; 73 import org.bouncycastle.asn1.x509.GeneralNames; 74 import org.bouncycastle.asn1.x509.PolicyInformation; 75 import org.bouncycastle.asn1.x509.ReasonFlags; 76 import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; 77 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 78 import org.bouncycastle.asn1.x509.X509DefaultEntryConverter; 79 import org.bouncycastle.asn1.x509.X509Extensions; 80 import org.bouncycastle.asn1.x509.X509Name; 81 import org.bouncycastle.asn1.x509.X509NameEntryConverter; 82 import org.bouncycastle.asn1.x509.X509NameTokenizer; 83 import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; 84 import org.bouncycastle.jce.X509KeyUsage; 85 import org.bouncycastle.jce.interfaces.ConfigurableProvider; 86 import org.bouncycastle.jce.provider.BouncyCastleProvider; 87 import org.bouncycastle.math.ec.ECCurve; 88 import org.bouncycastle.util.encoders.Hex; 89 import org.bouncycastle.x509.X509V3CertificateGenerator; 90 import org.ejbca.core.model.ca.crl.RevokedCertInfo; 91 import org.ejbca.util.dn.DNFieldExtractor; 92 import org.ejbca.util.dn.DnComponents; 93 94 95 100 public class CertTools { 101 private static Logger log = Logger.getLogger(CertTools.class); 102 103 static { 105 DnComponents.getDnObjects(); 106 } 107 public static final String EMAIL = "rfc822name"; 108 public static final String EMAIL1 = "email"; 109 public static final String EMAIL2 = "EmailAddress"; 110 public static final String EMAIL3 = "E"; 111 public static final String DNS = "dNSName"; 112 public static final String URI = "uniformResourceIdentifier"; 113 public static final String URI1 = "uri"; 114 public static final String URI2 = "uniformResourceId"; 115 public static final String IPADDR = "iPAddress"; 116 public static final String DIRECTORYNAME = "directoryName"; 117 118 119 public static final String UPN = "upn"; 120 121 public static final String UPN_OBJECTID = "1.3.6.1.4.1.311.20.2.3"; 122 123 public static final String GUID = "guid"; 124 125 public static final String GUID_OBJECTID = "1.3.6.1.4.1.311.25.1"; 126 127 public static final String id_pkix = "1.3.6.1.5.5.7"; 128 129 public static final String id_pda = id_pkix + ".9"; 130 133 public static final String id_pda_dateOfBirth = id_pda + ".1"; 134 137 public static final String id_pda_placeOfBirth = id_pda + ".2"; 138 142 public static final String id_pda_gender = id_pda + ".3"; 143 147 public static final String id_pda_countryOfCitizenship = id_pda + ".4"; 148 152 public static final String id_pda_countryOfResidence = id_pda + ".5"; 153 154 public static final String QCSTATEMENTS_OBJECTID = "1.3.6.1.5.5.7.1.3"; 155 156 public static final String OID_MSTEMPLATE = "1.3.6.1.4.1.311.20.2"; 157 158 159 private static final String [] EMAILIDS = { EMAIL, EMAIL1, EMAIL2, EMAIL3 }; 160 161 163 165 168 private static String IMPLICITLYCA_Q = "@ecdsa.implicitlyca.q@"; 169 private static String IMPLICITLYCA_A = "@ecdsa.implicitlyca.a@"; 170 private static String IMPLICITLYCA_B = "@ecdsa.implicitlyca.b@"; 171 private static String IMPLICITLYCA_G = "@ecdsa.implicitlyca.g@"; 172 private static String IMPLICITLYCA_N = "@ecdsa.implicitlyca.n@"; 173 174 179 private static final boolean developmentProviderInstallation = BooleanUtils.toBoolean("@development.provider.installation@"); 180 181 184 protected CertTools() { 185 } 186 187 197 public static X509Name stringToBcX509Name(String dn) { 198 X509NameEntryConverter converter = new X509DefaultEntryConverter(); 199 return stringToBcX509Name(dn, converter); 200 201 202 } 203 219 public static X509Name stringToBcX509Name(String dn, X509NameEntryConverter converter) { 220 if (dn == null) 222 return null; 223 224 Vector defaultOrdering = new Vector (); 225 Vector values = new Vector (); 226 X509NameTokenizer xt = new X509NameTokenizer(dn); 227 228 while (xt.hasMoreTokens()) { 229 String pair = xt.nextToken(); 231 int ix = pair.indexOf("="); 232 233 if (ix != -1) { 234 String key = pair.substring(0, ix).toLowerCase(); 235 String val = pair.substring(ix + 1); 236 237 DERObjectIdentifier oid = DnComponents.getOid(key); 239 240 try { 241 if (oid == null) { 243 oid = new DERObjectIdentifier(key); 244 } 245 defaultOrdering.add(oid); 246 values.add(val); 247 } catch (IllegalArgumentException e) { 248 log.warn("Unknown DN component ignored and silently dropped: " + key); 250 } 251 252 } else { 253 log.warn("Huh, what's this? DN: " + dn+" PAIR: "+pair); 254 } 255 } 256 257 X509Name x509Name = new X509Name(defaultOrdering, values, converter); 258 259 X509Name orderedX509Name = getOrderedX509Name(x509Name, getDefaultX509FieldOrder(), converter); 261 262 return orderedX509Name; 264 } 266 267 268 276 public static String stringToBCDNString(String dn) { 277 if (isDNReversed(dn)) { 279 dn = reverseDN(dn); 280 } 281 String ret = null; 282 X509Name name = stringToBcX509Name(dn); 283 if (name != null) { 284 ret = name.toString(); 285 } 286 return ret; 288 } 289 290 300 public static ArrayList getEmailFromDN(String dn) { 301 log.debug(">getEmailFromDN(" + dn + ")"); 302 ArrayList ret = new ArrayList (); 303 for (int i = 0; i < EMAILIDS.length ; i++) { 304 ArrayList emails = getPartsFromDN(dn, EMAILIDS[i]); 305 if (emails.size() > 0) { 306 ret.addAll(emails); 307 } 308 309 } 310 log.debug("<getEmailFromDN(" + dn + "): " + ret.size()); 311 return ret; 312 } 313 314 322 public static String getEMailAddress(X509Certificate certificate) { 323 log.debug("Searching for EMail Address in SubjectAltName"); 324 if (certificate == null) { 325 return null; 326 } 327 try { 328 if (certificate.getSubjectAlternativeNames() != null) { 329 java.util.Collection altNames = certificate.getSubjectAlternativeNames(); 330 Iterator iter = altNames.iterator(); 331 while (iter.hasNext()) { 332 java.util.List item = (java.util.List )iter.next(); 333 Integer type = (Integer )item.get(0); 334 if (type.intValue() == 1) { 335 return (String )item.get(1); 336 } 337 } 338 } 339 } catch (CertificateParsingException e) { 340 log.error("Error parsing certificate: ", e); 341 } 342 log.debug("Searching for EMail Address in Subject DN"); 343 ArrayList emails = CertTools.getEmailFromDN(certificate.getSubjectDN().getName()); 344 if (emails.size() > 0) { 345 return (String )emails.get(0); 346 } 347 return null; 348 } 349 350 358 public static String reverseDN(String dn) { 359 log.debug(">reverseDN: dn: " + dn); 360 String ret = null; 361 if (dn != null) { 362 String o; 363 BasicX509NameTokenizer xt = new BasicX509NameTokenizer(dn); 364 StringBuffer buf = new StringBuffer (); 365 boolean first = true; 366 while (xt.hasMoreTokens()) { 367 o = xt.nextToken(); 368 if (!first) { 370 buf.insert(0,","); 371 } else { 372 first = false; 373 } 374 buf.insert(0,o); 375 } 376 if (buf.length() > 0) { 377 ret = buf.toString(); 378 } 379 } 380 381 log.debug("<reverseDN: resulting dn: " + ret); 382 return ret; 383 } 385 400 protected static boolean isDNReversed(String dn) { 401 boolean ret = false; 403 if (dn != null) { 404 String first = null; 405 String last = null; 406 X509NameTokenizer xt = new X509NameTokenizer(dn); 407 if (xt.hasMoreTokens()) { 408 first = xt.nextToken(); 409 } 410 while (xt.hasMoreTokens()) { 411 last = xt.nextToken(); 412 } 413 String [] dNObjects = DnComponents.getDnObjects(); 414 if ( (first != null) && (last != null) ) { 415 first = first.substring(0,first.indexOf('=')); 416 last = last.substring(0,last.indexOf('=')); 417 int firsti = 0, lasti = 0; 418 for (int i = 0; i < dNObjects.length; i++) { 419 if (first.toLowerCase().equals(dNObjects[i])) { 420 firsti = i; 421 } 422 if (last.toLowerCase().equals(dNObjects[i])) { 423 lasti = i; 424 } 425 } 426 if (lasti < firsti) { 427 ret = true; 428 } 429 430 } 431 } 432 return ret; 434 } 436 445 public static String getPartFromDN(String dn, String dnpart) { 446 log.debug(">getPartFromDN: dn:'" + dn + "', dnpart=" + dnpart); 447 String part = null; 448 if ((dn != null) && (dnpart != null)) { 449 String o; 450 dnpart += "="; X509NameTokenizer xt = new X509NameTokenizer(dn); 452 while (xt.hasMoreTokens()) { 453 o = xt.nextToken(); 454 if ((o.length() > dnpart.length()) && 456 o.substring(0, dnpart.length()).equalsIgnoreCase(dnpart)) { 457 part = o.substring(dnpart.length()); 458 459 break; 460 } 461 } 462 } 463 log.debug("<getpartFromDN: resulting DN part=" + part); 464 return part; 465 } 467 476 public static ArrayList getPartsFromDN(String dn, String dnpart) { 477 log.debug(">getPartsFromDN: dn:'" + dn + "', dnpart=" + dnpart); 478 ArrayList parts = new ArrayList (); 479 if ((dn != null) && (dnpart != null)) { 480 String o; 481 dnpart += "="; X509NameTokenizer xt = new X509NameTokenizer(dn); 483 while (xt.hasMoreTokens()) { 484 o = xt.nextToken(); 485 if ((o.length() > dnpart.length()) && 486 o.substring(0, dnpart.length()).equalsIgnoreCase(dnpart)) { 487 parts.add(o.substring(dnpart.length())); 488 } 489 } 490 } 491 log.debug("<getpartsFromDN: resulting DN part=" + parts.toString()); 492 return parts; 493 } 495 503 public static ArrayList getCustomOids(String dn) { 504 log.debug(">getCustomOids: dn:'" + dn); 505 ArrayList parts = new ArrayList (); 506 if (dn != null) { 507 String o; 508 X509NameTokenizer xt = new X509NameTokenizer(dn); 509 while (xt.hasMoreTokens()) { 510 o = xt.nextToken(); 511 try { 513 int i = o.indexOf('='); 514 if ( (i > 2) && (o.charAt(1) == '.') ) { 516 String oid = o.substring(0, i); 517 new DERObjectIdentifier(oid); 518 parts.add(oid); 519 } 520 } catch (IllegalArgumentException e) { 521 } 523 } 524 } 525 log.debug("<getpartsFromDN: resulting DN part=" + parts.toString()); 526 return parts; 527 } 529 536 public static String getSubjectDN(X509Certificate cert) { 537 return getDN(cert, 1); 538 } 539 540 547 public static String getIssuerDN(X509Certificate cert) { 548 return getDN(cert, 2); 549 } 550 551 559 private static String getDN(X509Certificate cert, int which) { 560 String dn = null; 562 if (cert == null) { 563 return dn; 564 } 565 try { 566 CertificateFactory cf = CertTools.getCertificateFactory(); 567 X509Certificate x509cert = (X509Certificate ) cf.generateCertificate(new ByteArrayInputStream ( 568 cert.getEncoded())); 569 571 if (which == 1) { 572 dn = x509cert.getSubjectDN().toString(); 573 } else { 574 dn = x509cert.getIssuerDN().toString(); 575 } 576 } catch (CertificateException ce) { 577 log.error("CertificateException: ", ce); 578 return null; 579 } 580 return stringToBCDNString(dn); 582 } 584 591 public static String getIssuerDN(X509CRL crl) { 592 String dn = null; 594 try { 595 CertificateFactory cf = CertTools.getCertificateFactory(); 596 X509CRL x509crl = (X509CRL ) cf.generateCRL(new ByteArrayInputStream (crl.getEncoded())); 597 dn = x509crl.getIssuerDN().toString(); 599 } catch (CRLException ce) { 600 log.error("CRLException: ", ce); 601 return null; 602 } 603 return stringToBCDNString(dn); 605 } 607 public static CertificateFactory getCertificateFactory() { 608 try { 609 return CertificateFactory.getInstance("X.509", "BC"); 610 } catch (NoSuchProviderException nspe) { 611 log.error("NoSuchProvider: ", nspe); 612 } catch (CertificateException ce) { 613 log.error("CertificateException: ", ce); 614 } 615 return null; 616 } 617 618 public static synchronized void removeBCProvider() { 619 Security.removeProvider("BC"); 620 } 621 public static synchronized void installBCProvider() { 622 boolean installImplicitlyCA = false; 624 if (Security.addProvider(new BouncyCastleProvider()) < 0) { 625 if (developmentProviderInstallation) { 630 removeBCProvider(); 631 if (Security.addProvider(new BouncyCastleProvider()) < 0) { 632 log.error("Cannot even install BC provider again!"); 633 } else { 634 installImplicitlyCA = true; 635 } 636 } 637 } else { 638 installImplicitlyCA = true; 639 } 640 if (installImplicitlyCA) { 641 checkImplicitParams(); 644 ECCurve curve = new ECCurve.Fp( 645 new BigInteger (IMPLICITLYCA_Q), new BigInteger (IMPLICITLYCA_A, 16), new BigInteger (IMPLICITLYCA_B, 16)); org.bouncycastle.jce.spec.ECParameterSpec implicitSpec = new org.bouncycastle.jce.spec.ECParameterSpec( 649 curve, 650 curve.decodePoint(Hex.decode(IMPLICITLYCA_G)), new BigInteger (IMPLICITLYCA_N)); ConfigurableProvider config = (ConfigurableProvider)Security.getProvider("BC"); 653 if (config != null) { 654 config.setParameter(ConfigurableProvider.EC_IMPLICITLY_CA, implicitSpec); 655 } else { 656 log.error("Can not get ConfigurableProvider, implicitlyCA EC parameters NOT set!"); 657 } 658 } 659 660 X509Name.DefaultSymbols.put(X509Name.SN, "SN"); 665 } 666 667 670 private static void checkImplicitParams() { 671 if (StringUtils.contains(IMPLICITLYCA_Q, "ecdsa.implicitlyca.q")) { 672 log.error("IMPLICITLYCA_Q not set!"); 673 IMPLICITLYCA_Q = "883423532389192164791648750360308885314476597252960362792450860609699839"; 674 } 675 if (StringUtils.contains(IMPLICITLYCA_A, "ecdsa.implicitlyca.a")) { 676 log.error("IMPLICITLYCA_A not set!"); 677 IMPLICITLYCA_A = "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"; 678 } 679 if (StringUtils.contains(IMPLICITLYCA_B, "ecdsa.implicitlyca.b")) { 680 log.error("IMPLICITLYCA_B not set!"); 681 IMPLICITLYCA_B = "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"; 682 } 683 if (StringUtils.contains(IMPLICITLYCA_G, "ecdsa.implicitlyca.g")) { 684 log.error("IMPLICITLYCA_G not set!"); 685 IMPLICITLYCA_G = "020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf"; 686 } 687 if (StringUtils.contains(IMPLICITLYCA_N, "ecdsa.implicitlyca.n")) { 688 log.error("IMPLICITLYCA_N not set!"); 689 IMPLICITLYCA_N = "883423532389192164791648750360308884807550341691627752275345424702807307"; 690 } 691 } 692 693 702 public static Collection getCertsFromPEM(String certFile) throws IOException , CertificateException { 703 log.debug(">getCertfromPEM: certFile=" + certFile); 704 InputStream inStrm = null; 705 Collection certs; 706 try { 707 inStrm = new FileInputStream (certFile); 708 certs = getCertsFromPEM(inStrm); 709 } finally { 710 if (inStrm != null) inStrm.close(); 711 } 712 log.debug("<getCertfromPEM: certFile=" + certFile); 713 return certs; 714 } 715 716 725 public static Collection getCertsFromPEM(InputStream certstream) 726 throws IOException , CertificateException { 727 log.debug(">getCertfromPEM:"); 728 ArrayList ret = new ArrayList (); 729 String beginKey = "-----BEGIN CERTIFICATE-----"; 730 String endKey = "-----END CERTIFICATE-----"; 731 BufferedReader bufRdr = null; 732 ByteArrayOutputStream ostr = null; 733 PrintStream opstr = null; 734 try { 735 bufRdr = new BufferedReader (new InputStreamReader (certstream)); 736 while (bufRdr.ready()) { 737 ostr = new ByteArrayOutputStream (); 738 opstr = new PrintStream (ostr); 739 String temp; 740 while ((temp = bufRdr.readLine()) != null 741 && !temp.equals(beginKey)) 742 continue; 743 if (temp == null) 744 throw new IOException ("Error in " + certstream.toString() 745 + ", missing " + beginKey + " boundary"); 746 while ((temp = bufRdr.readLine()) != null 747 && !temp.equals(endKey)) 748 opstr.print(temp); 749 if (temp == null) 750 throw new IOException ("Error in " + certstream.toString() 751 + ", missing " + endKey + " boundary"); 752 opstr.close(); 753 754 byte[] certbuf = Base64.decode(ostr.toByteArray()); 755 ostr.close(); 756 CertificateFactory cf = CertTools.getCertificateFactory(); 758 X509Certificate x509cert = (X509Certificate )cf.generateCertificate(new ByteArrayInputStream (certbuf)); 759 ret.add(x509cert); 760 } 761 } finally { 762 if (bufRdr != null) bufRdr.close(); 763 if (opstr != null) opstr.close(); 764 if (ostr != null) ostr.close(); 765 } 766 log.debug("<getcertfromPEM:" + ret.size()); 767 return ret; 768 } 770 778 public static ArrayList getCertCollectionFromArray(Certificate [] certs, String provider) throws CertificateException , NoSuchProviderException { 779 log.debug(">getCertCollectionFromArray: "+provider); 780 ArrayList ret = new ArrayList (); 781 String prov = provider; 782 if (prov == null) { 783 prov = "BC"; 784 } 785 for (int i=0; i < certs.length; i++) { 786 CertificateFactory cf = CertificateFactory.getInstance("X.509", prov); 787 Certificate cert = certs[i]; 788 X509Certificate x509cert = (X509Certificate )cf.generateCertificate(new ByteArrayInputStream (cert.getEncoded())); 789 ret.add(x509cert); 790 } 791 log.debug("<getCertCollectionFromArray: "+ret.size()); 792 return ret; 793 } 794 795 803 public static byte[] getPEMFromCerts(Collection certs) 804 throws CertificateException { 805 String beginKey = "-----BEGIN CERTIFICATE-----"; 806 String endKey = "-----END CERTIFICATE-----"; 807 ByteArrayOutputStream ostr = new ByteArrayOutputStream (); 808 PrintStream opstr = new PrintStream (ostr); 809 Iterator iter = certs.iterator(); 810 while (iter.hasNext()) { 811 X509Certificate cert = (X509Certificate )iter.next(); 812 byte[] certbuf = Base64.encode(cert.getEncoded()); 813 opstr.println("Subject: "+cert.getSubjectDN()); 814 opstr.println("Issuer: "+cert.getIssuerDN()); 815 opstr.println(beginKey); 816 opstr.println(new String (certbuf)); 817 opstr.println(endKey); 818 } 819 opstr.close(); 820 byte[] ret = ostr.toByteArray(); 821 return ret; 822 } 823 824 834 public static X509Certificate getCertfromByteArray(byte[] cert) 835 throws CertificateException { 836 log.debug(">getCertfromByteArray:"); 837 CertificateFactory cf = CertTools.getCertificateFactory(); 838 X509Certificate x509cert = (X509Certificate ) cf.generateCertificate(new ByteArrayInputStream (cert)); 839 log.debug("<getCertfromByteArray:"); 840 return x509cert; 841 } 843 854 public static X509CRL getCRLfromByteArray(byte[] crl) 855 throws IOException , CRLException { 856 log.debug(">getCRLfromByteArray:"); 857 858 if (crl == null) { 859 throw new IOException ("Cannot read byte[] that is 'null'!"); 860 } 861 862 CertificateFactory cf = CertTools.getCertificateFactory(); 863 X509CRL x509crl = (X509CRL ) cf.generateCRL(new ByteArrayInputStream (crl)); 864 log.debug("<getCRLfromByteArray:"); 865 866 return x509crl; 867 } 869 876 public static boolean isSelfSigned(X509Certificate cert) { 877 log.debug(">isSelfSigned: cert: " + CertTools.getIssuerDN(cert) + "\n" + 878 CertTools.getSubjectDN(cert)); 879 880 boolean ret = CertTools.getSubjectDN(cert).equals(CertTools.getIssuerDN(cert)); 881 log.debug("<isSelfSigned:" + ret); 882 883 return ret; 884 } 886 905 public static X509Certificate genSelfCert(String dn, long validity, String policyId, 906 PrivateKey privKey, PublicKey pubKey, String sigAlg, boolean isCA) 907 throws NoSuchAlgorithmException , SignatureException , InvalidKeyException , CertificateEncodingException , IllegalStateException { 908 909 int keyusage = X509KeyUsage.keyCertSign + X509KeyUsage.cRLSign; 910 return genSelfCertForPurpose(dn, validity, policyId, privKey, pubKey, sigAlg, isCA, keyusage); 911 912 } 914 934 public static X509Certificate genSelfCertForPurpose(String dn, long validity, String policyId, 935 PrivateKey privKey, PublicKey pubKey, String sigAlg, boolean isCA, int keyusage) 936 throws NoSuchAlgorithmException , SignatureException , InvalidKeyException , CertificateEncodingException , IllegalStateException { 937 Date firstDate = new Date (); 939 940 firstDate.setTime(firstDate.getTime() - (10 * 60 * 1000)); 942 943 Date lastDate = new Date (); 944 945 lastDate.setTime(lastDate.getTime() + (validity * (24 * 60 * 60 * 1000))); 947 948 X509V3CertificateGenerator certgen = new X509V3CertificateGenerator(); 949 950 byte[] serno = new byte[8]; 953 SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 954 random.setSeed((new Date ().getTime())); 955 random.nextBytes(serno); 956 certgen.setSerialNumber((new java.math.BigInteger (serno)).abs()); 957 certgen.setNotBefore(firstDate); 958 certgen.setNotAfter(lastDate); 959 certgen.setSignatureAlgorithm(sigAlg); 960 certgen.setSubjectDN(CertTools.stringToBcX509Name(dn)); 961 certgen.setIssuerDN(CertTools.stringToBcX509Name(dn)); 962 certgen.setPublicKey(pubKey); 963 964 BasicConstraints bc = new BasicConstraints(isCA); 966 certgen.addExtension(X509Extensions.BasicConstraints.getId(), true, bc); 967 968 if (isCA == true) { 970 X509KeyUsage ku = new X509KeyUsage(keyusage); 971 certgen.addExtension(X509Extensions.KeyUsage.getId(), true, ku); 972 } 973 974 try { 976 if (isCA == true) { 977 SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo((ASN1Sequence) new ASN1InputStream( 978 new ByteArrayInputStream (pubKey.getEncoded())).readObject()); 979 SubjectKeyIdentifier ski = new SubjectKeyIdentifier(spki); 980 981 SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence) new ASN1InputStream( 982 new ByteArrayInputStream (pubKey.getEncoded())).readObject()); 983 AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki); 984 985 certgen.addExtension(X509Extensions.SubjectKeyIdentifier.getId(), false, ski); 986 certgen.addExtension(X509Extensions.AuthorityKeyIdentifier.getId(), false, aki); 987 } 988 } catch (IOException e) { } 990 991 if (policyId != null) { 993 PolicyInformation pi = new PolicyInformation(new DERObjectIdentifier(policyId)); 994 DERSequence seq = new DERSequence(pi); 995 certgen.addExtension(X509Extensions.CertificatePolicies.getId(), false, seq); 996 } 997 998 X509Certificate selfcert = certgen.generate(privKey); 999 1000 return selfcert; 1001 } 1003 1010 public static byte[] getAuthorityKeyId(X509Certificate cert) 1011 throws IOException { 1012 if (cert == null) { 1013 return null; 1014 } 1015 byte[] extvalue = cert.getExtensionValue("2.5.29.35"); 1016 if (extvalue == null) { 1017 return null; 1018 } 1019 DEROctetString oct = (DEROctetString) (new ASN1InputStream(new ByteArrayInputStream (extvalue)).readObject()); 1020 AuthorityKeyIdentifier keyId = new AuthorityKeyIdentifier((ASN1Sequence) new ASN1InputStream( 1021 new ByteArrayInputStream (oct.getOctets())).readObject()); 1022 return keyId.getKeyIdentifier(); 1023 } 1025 1032 public static byte[] getSubjectKeyId(X509Certificate cert) 1033 throws IOException { 1034 if (cert == null) { 1035 return null; 1036 } 1037 byte[] extvalue = cert.getExtensionValue("2.5.29.14"); 1038 if (extvalue == null) { 1039 return null; 1040 } 1041 ASN1OctetString str = ASN1OctetString.getInstance(new ASN1InputStream(new ByteArrayInputStream (extvalue)).readObject()); 1042 SubjectKeyIdentifier keyId = SubjectKeyIdentifier.getInstance(new ASN1InputStream(new ByteArrayInputStream (str.getOctets())).readObject()); 1043 return keyId.getKeyIdentifier(); 1044 } 1046 1054 public static String getCertificatePolicyId(X509Certificate cert, int pos) 1055 throws IOException { 1056 byte[] extvalue = cert.getExtensionValue(X509Extensions.CertificatePolicies.getId()); 1057 if (extvalue == null) { 1058 return null; 1059 } 1060 DEROctetString oct = (DEROctetString) (new ASN1InputStream(new ByteArrayInputStream (extvalue)).readObject()); 1061 ASN1Sequence seq = (ASN1Sequence)new ASN1InputStream(new ByteArrayInputStream (oct.getOctets())).readObject(); 1062 if (seq.size() < pos+1) { 1064 return null; 1065 } 1066 PolicyInformation pol = new PolicyInformation((ASN1Sequence)seq.getObjectAt(pos)); 1067 String id = pol.getPolicyIdentifier().getId(); 1068 return id; 1069 } 1071 1077 public static String getUPNAltName(X509Certificate cert) throws IOException , CertificateParsingException { 1078 Collection altNames = cert.getSubjectAlternativeNames(); 1079 if (altNames != null) { 1080 Iterator i = altNames.iterator(); 1081 while (i.hasNext()) { 1082 ASN1Sequence seq = getAltnameSequence((List )i.next()); 1083 String ret = getUPNStringFromSequence(seq); 1084 if (ret != null) { 1085 return ret; 1086 } 1087 } 1088 } 1089 return null; 1090 } 1092 1094 private static String getUPNStringFromSequence(ASN1Sequence seq) { 1095 if ( seq != null) { 1096 DERObjectIdentifier id = DERObjectIdentifier.getInstance(seq.getObjectAt(0)); 1098 if (id.getId().equals(CertTools.UPN_OBJECTID)) { 1099 ASN1TaggedObject obj = (ASN1TaggedObject) seq.getObjectAt(1); 1100 DERUTF8String str = DERUTF8String.getInstance(obj.getObject()); 1101 return str.getString(); 1102 } 1103 } 1104 return null; 1105 } 1106 1107 1113 public static String getGuidAltName(X509Certificate cert) 1114 throws IOException , CertificateParsingException { 1115 Collection altNames = cert.getSubjectAlternativeNames(); 1116 if (altNames != null) { 1117 Iterator i = altNames.iterator(); 1118 while (i.hasNext()) { 1119 ASN1Sequence seq = getAltnameSequence((List )i.next()); 1120 if ( seq != null) { 1121 DERObjectIdentifier id = DERObjectIdentifier.getInstance(seq.getObjectAt(0)); 1123 if (id.getId().equals(CertTools.GUID_OBJECTID)) { 1124 ASN1TaggedObject obj = (ASN1TaggedObject) seq.getObjectAt(1); 1125 ASN1OctetString str = ASN1OctetString.getInstance(obj.getObject()); 1126 return new String (Hex.encode(str.getOctets())); 1127 } 1128 } 1129 } 1130 } 1131 return null; 1132 } 1134 1136 private static ASN1Sequence getAltnameSequence(List listitem) throws IOException { 1137 Integer no = (Integer ) listitem.get(0); 1138 if (no.intValue() == 0) { 1139 byte[] altName = (byte[]) listitem.get(1); 1140 return getAltnameSequence(altName); 1141 } 1142 return null; 1143 } 1144 private static ASN1Sequence getAltnameSequence(byte[] value) throws IOException { 1145 DERObject oct = (new ASN1InputStream(new ByteArrayInputStream (value)).readObject()); 1146 ASN1Sequence seq = ASN1Sequence.getInstance(oct); 1147 return seq; 1148 } 1149 1150 1178 public static String getSubjectAlternativeName(X509Certificate certificate) throws Exception { 1179 log.debug("Search for SubjectAltName"); 1180 if (certificate.getSubjectAlternativeNames() == null) 1181 return null; 1182 1183 java.util.Collection altNames = certificate.getSubjectAlternativeNames(); 1184 if (altNames == null) { 1185 return null; 1186 } 1187 Iterator iter = altNames.iterator(); 1188 String result = ""; 1189 String append = ""; 1190 while (iter.hasNext()) { 1191 java.util.List item = (java.util.List )iter.next(); 1192 Integer type = (Integer )item.get(0); 1193 Object value = item.get(1); 1194 if (!StringUtils.isEmpty(result)) { 1195 append = ", "; 1197 } 1198 switch (type.intValue()) { 1199 case 0: ASN1Sequence seq = getAltnameSequence(item); 1200 String upn = getUPNStringFromSequence(seq); 1201 if (upn != null) { 1203 result += append + CertTools.UPN+"="+upn; 1204 } 1205 break; 1206 case 1: result += append + CertTools.EMAIL+"=" + (String )value; 1207 break; 1208 case 2: result += append + CertTools.DNS+"=" + (String )value; 1209 break; 1210 case 3: break; 1212 case 4: result += append + CertTools.DIRECTORYNAME+"=" + (String )value; 1213 break; 1214 case 5: break; 1216 case 6: result += append + CertTools.URI+"=" + (String )value; 1217 break; 1218 case 7: result += append + CertTools.IPADDR+"=" + (String )value; 1219 break; 1220 default: break; 1222 } 1223 } 1224 if (StringUtils.isEmpty(result)) { 1225 return null; 1226 } 1227 return result; 1228 } 1229 1230 1236 public static GeneralNames getGeneralNamesFromAltName(String altName) { 1237 log.debug(">getGeneralNamesFromAltName: "+altName); 1238 1239 ASN1EncodableVector vec = new ASN1EncodableVector(); 1240 1241 ArrayList emails = CertTools.getEmailFromDN(altName); 1242 if (!emails.isEmpty()) { 1243 Iterator iter = emails.iterator(); 1244 while (iter.hasNext()) { 1245 GeneralName gn = new GeneralName(1, new DERIA5String((String )iter.next())); 1246 vec.add(gn); 1247 } 1248 } 1249 1250 ArrayList dns = CertTools.getPartsFromDN(altName, CertTools.DNS); 1251 if (!dns.isEmpty()) { 1252 Iterator iter = dns.iterator(); 1253 while (iter.hasNext()) { 1254 GeneralName gn = new GeneralName(2, new DERIA5String((String )iter.next())); 1255 vec.add(gn); 1256 } 1257 } 1258 1259 String directoryName = getDirectoryStringFromAltName(altName); 1260 if (directoryName != null) { 1261 X509Name x509DirectoryName = new X509Name(directoryName); 1262 GeneralName gn = new GeneralName(4, x509DirectoryName); 1263 vec.add(gn); 1264 } 1265 1266 ArrayList uri = CertTools.getPartsFromDN(altName, CertTools.URI); 1267 if (!uri.isEmpty()) { 1268 Iterator iter = uri.iterator(); 1269 while (iter.hasNext()) { 1270 GeneralName gn = new GeneralName(6, new DERIA5String((String )iter.next())); 1271 vec.add(gn); 1272 } 1273 } 1274 uri = CertTools.getPartsFromDN(altName, CertTools.URI1); 1275 if (!uri.isEmpty()) { 1276 Iterator iter = uri.iterator(); 1277 while (iter.hasNext()) { 1278 GeneralName gn = new GeneralName(6, new DERIA5String((String )iter.next())); 1279 vec.add(gn); 1280 } 1281 } 1282 uri = CertTools.getPartsFromDN(altName, CertTools.URI2); 1283 if (!uri.isEmpty()) { 1284 Iterator iter = uri.iterator(); 1285 while (iter.hasNext()) { 1286 GeneralName gn = new GeneralName(6, new DERIA5String((String )iter.next())); 1287 vec.add(gn); 1288 } 1289 } 1290 1291 1292 ArrayList ipstr = CertTools.getPartsFromDN(altName, CertTools.IPADDR); 1293 if (!ipstr.isEmpty()) { 1294 Iterator iter = ipstr.iterator(); 1295 while (iter.hasNext()) { 1296 byte[] ipoctets = StringTools.ipStringToOctets((String )iter.next()); 1297 GeneralName gn = new GeneralName(7, new DEROctetString(ipoctets)); 1298 vec.add(gn); 1299 } 1300 } 1301 1302 ArrayList upn = CertTools.getPartsFromDN(altName, CertTools.UPN); 1304 if (!upn.isEmpty()) { 1305 Iterator iter = upn.iterator(); 1306 while (iter.hasNext()) { 1307 ASN1EncodableVector v = new ASN1EncodableVector(); 1308 v.add(new DERObjectIdentifier(CertTools.UPN_OBJECTID)); 1309 v.add(new DERTaggedObject(true, 0, new DERUTF8String((String )iter.next()))); 1310 DERObject gn = new DERTaggedObject(false, 0, new DERSequence(v)); 1312 vec.add(gn); 1313 } 1314 } 1315 1316 1317 ArrayList guid = CertTools.getPartsFromDN(altName, CertTools.GUID); 1318 if (!guid.isEmpty()) { 1319 Iterator iter = guid.iterator(); 1320 while (iter.hasNext()) { 1321 ASN1EncodableVector v = new ASN1EncodableVector(); 1322 byte[] guidbytes = Hex.decode((String )iter.next()); 1323 if (guidbytes != null) { 1324 v.add(new DERObjectIdentifier(CertTools.GUID_OBJECTID)); 1325 v.add(new DERTaggedObject(true, 0, new DEROctetString(guidbytes))); 1326 DERObject gn = new DERTaggedObject(false, 0, new DERSequence(v)); 1327 vec.add(gn); 1328 } else { 1329 log.error("Cannot decode hexadecimal guid: "+guid); 1330 } 1331 } 1332 } 1333 1334 ArrayList customoids = CertTools.getCustomOids(altName); 1336 if (!customoids.isEmpty()) { 1337 Iterator iter = customoids.iterator(); 1338 while (iter.hasNext()) { 1339 String oid = (String )iter.next(); 1340 ArrayList oidval = CertTools.getPartsFromDN(altName, oid); 1341 if (!oidval.isEmpty()) { 1342 Iterator valiter = oidval.iterator(); 1343 while (valiter.hasNext()) { 1344 ASN1EncodableVector v = new ASN1EncodableVector(); 1345 v.add(new DERObjectIdentifier(oid)); 1346 v.add(new DERTaggedObject(true, 0, new DERUTF8String((String )valiter.next()))); 1347 DERObject gn = new DERTaggedObject(false, 0, new DERSequence(v)); 1348 vec.add(gn); 1349 } 1350 } 1351 } 1352 } 1353 1354 GeneralNames ret = null; 1355 if (vec.size() > 0) { 1356 ret = new GeneralNames(new DERSequence(vec)); 1357 } 1358 return ret; 1359 } 1360 1361 1379 public static String getGeneralNameString(int tag, DEREncodable value) throws IOException { 1380 String ret = null; 1381 switch (tag) { 1382 case 0: ASN1Sequence seq = getAltnameSequence(value.getDERObject().getEncoded()); 1383 String upn = getUPNStringFromSequence(seq); 1384 if (upn != null) { 1386 ret = CertTools.UPN+"="+upn; 1387 } 1388 break; 1389 case 1: ret = CertTools.EMAIL+"=" + DERIA5String.getInstance(value).getString(); 1390 break; 1391 case 2: ret = CertTools.DNS+"=" + DERIA5String.getInstance(value).getString(); 1392 break; 1393 case 3: break; 1395 case 4: break; 1397 case 5: break; 1399 case 6: ret = CertTools.URI+"=" + DERIA5String.getInstance(value).getString(); 1400 break; 1401 case 7: break; 1403 default: break; 1405 } 1406 return ret; 1407 } 1408 1409 1416 public static boolean verify(X509Certificate certificate, Collection caCertPath) throws Exception { 1417 try { 1418 ArrayList certlist = new ArrayList (); 1419 certlist.add(certificate); 1421 CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); 1423 java.security.cert.CertPath cp = cf.generateCertPath(certlist); 1424 X509Certificate [] cac = (X509Certificate []) caCertPath.toArray(new X509Certificate [] {}); 1427 java.security.cert.TrustAnchor anchor = new java.security.cert. 1428 TrustAnchor(cac[0], null); 1429 java.security.cert.PKIXParameters params = new java.security.cert.PKIXParameters (java.util.Collections.singleton(anchor)); 1431 params.setRevocationEnabled(false); 1432 java.security.cert.CertPathValidator cpv = java.security.cert. 1433 CertPathValidator.getInstance("PKIX", "BC"); 1434 java.security.cert.PKIXCertPathValidatorResult result = 1435 (java.security.cert.PKIXCertPathValidatorResult ) cpv.validate(cp, params); 1436 log.debug("Certificate verify result: " + result.toString()); 1437 } catch (java.security.cert.CertPathValidatorException cpve) { 1438 throw new Exception ("Invalid certificate or certificate not issued by specified CA: " + cpve.getMessage()); 1439 } catch (Exception e) { 1440 throw new Exception ("Error checking certificate chain: " + e.getMessage()); 1441 } 1442 return true; 1443 } 1444 1445 1448 public static URL getCrlDistributionPoint(X509Certificate certificate) 1449 throws CertificateParsingException { 1450 try { 1451 DERObject obj = getExtensionValue(certificate, X509Extensions 1452 .CRLDistributionPoints.getId()); 1453 if (obj == null) { 1454 return null; 1455 } 1456 ASN1Sequence distributionPoints = (ASN1Sequence) obj; 1457 for (int i = 0; i < distributionPoints.size(); i++) { 1458 ASN1Sequence distrPoint = (ASN1Sequence) distributionPoints.getObjectAt(i); 1459 for (int j = 0; j < distrPoint.size(); j++) { 1460 ASN1TaggedObject tagged = (ASN1TaggedObject) distrPoint.getObjectAt(j); 1461 if (tagged.getTagNo() == 0) { 1462 String url 1463 = getStringFromGeneralNames(tagged.getObject()); 1464 if (url != null) { 1465 return new URL (url); 1466 } 1467 } 1468 } 1469 } 1470 } 1471 catch (Exception e) { 1472 log.error("Error parsing CrlDistributionPoint", e); 1473 throw new CertificateParsingException (e.toString()); 1474 } 1475 return null; 1476 } 1477 1478 1484 public static String getAuthorityInformationAccessOcspUrl(X509Certificate cert) 1485 throws CertificateParsingException { 1486 try { 1487 DERObject obj = getExtensionValue(cert, X509Extensions.AuthorityInfoAccess.getId()); 1488 if (obj == null) { 1489 return null; 1490 } 1491 AuthorityInformationAccess aia = AuthorityInformationAccess.getInstance(obj); 1492 AccessDescription[] ad = aia.getAccessDescriptions(); 1493 if ( (ad == null) || (ad.length < 1) ) { 1494 return null; 1495 } 1496 if (!ad[0].getAccessMethod().equals(X509ObjectIdentifiers.ocspAccessMethod)) { 1497 return null; 1498 } 1499 GeneralName gn = ad[0].getAccessLocation(); 1500 if (gn.getTagNo() != 6) { 1501 return null; 1502 } 1503 DERIA5String str = DERIA5String.getInstance(gn.getDERObject()); 1504 return str.getString(); 1505 } 1506 catch (Exception e) { 1507 log.error("Error parsing AuthorityInformationAccess", e); 1508 throw new CertificateParsingException (e.toString()); 1509 } 1510 } 1511 1512 1515 protected static DERObject getExtensionValue(X509Certificate cert, String oid) 1516 throws IOException { 1517 if (cert == null) { 1518 return null; 1519 } 1520 byte[] bytes = cert.getExtensionValue(oid); 1521 if (bytes == null) { 1522 return null; 1523 } 1524 ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream (bytes)); 1525 ASN1OctetString octs = (ASN1OctetString) aIn.readObject(); 1526 aIn = new ASN1InputStream(new ByteArrayInputStream (octs.getOctets())); 1527 return aIn.readObject(); 1528 } 1530 private static String getStringFromGeneralNames(DERObject names) { 1531 ASN1Sequence namesSequence = ASN1Sequence.getInstance((ASN1TaggedObject)names, false); 1532 if (namesSequence.size() == 0) { 1533 return null; 1534 } 1535 DERTaggedObject taggedObject 1536 = (DERTaggedObject)namesSequence.getObjectAt(0); 1537 return new String (ASN1OctetString.getInstance(taggedObject, false).getOctets()); 1538 } 1540 1547 public static String getCertFingerprintAsString(byte[] ba) { 1548 try { 1549 X509Certificate cert = getCertfromByteArray(ba); 1550 byte[] res = generateSHA1Fingerprint(cert.getEncoded()); 1551 1552 return new String (Hex.encode(res)); 1553 } catch (CertificateEncodingException cee) { 1554 log.error("Error encoding X509 certificate.", cee); 1555 } catch (CertificateException cee) { 1556 log.error("Error decoding X509 certificate.", cee); 1557 } 1558 1559 return null; 1560 } 1561 1562 1569 public static String getFingerprintAsString(X509Certificate cert) { 1570 if (cert == null) return null; 1571 try { 1572 byte[] res = generateSHA1Fingerprint(cert.getEncoded()); 1573 1574 return new String (Hex.encode(res)); 1575 } catch (CertificateEncodingException cee) { 1576 log.error("Error encoding X509 certificate.", cee); 1577 } 1578 1579 return null; 1580 } 1581 1582 1589 public static String getFingerprintAsString(X509CRL crl) { 1590 try { 1591 byte[] res = generateSHA1Fingerprint(crl.getEncoded()); 1592 1593 return new String (Hex.encode(res)); 1594 } catch (CRLException ce) { 1595 log.error("Error encoding X509 CRL.", ce); 1596 } 1597 1598 return null; 1599 } 1600 1601 1608 public static byte[] generateSHA1Fingerprint(byte[] ba) { 1609 try { 1610 MessageDigest md = MessageDigest.getInstance("SHA1"); 1611 1612 return md.digest(ba); 1613 } catch (NoSuchAlgorithmException nsae) { 1614 log.error("SHA1 algorithm not supported", nsae); 1615 } 1616 1617 return null; 1618 } 1620 1627 public static byte[] generateMD5Fingerprint(byte[] ba) { 1628 try { 1629 MessageDigest md = MessageDigest.getInstance("MD5"); 1630 1631 return md.digest(ba); 1632 } catch (NoSuchAlgorithmException nsae) { 1633 log.error("MD5 algorithm not supported", nsae); 1634 } 1635 1636 return null; 1637 } 1639 1646 public static int sunKeyUsageToBC(boolean[] sku) { 1647 if (sku == null) { 1648 return -1; 1649 } 1650 int bcku = 0; 1651 if (sku[0] == true) 1652 bcku = bcku | X509KeyUsage.digitalSignature; 1653 if (sku[1] == true) 1654 bcku = bcku | X509KeyUsage.nonRepudiation; 1655 if (sku[2] == true) 1656 bcku = bcku | X509KeyUsage.keyEncipherment; 1657 if (sku[3] == true) 1658 bcku = bcku | X509KeyUsage.dataEncipherment; 1659 if (sku[4] == true) 1660 bcku = bcku | X509KeyUsage.keyAgreement; 1661 if (sku[5] == true) 1662 bcku = bcku | X509KeyUsage.keyCertSign; 1663 if (sku[6] == true) 1664 bcku = bcku | X509KeyUsage.cRLSign; 1665 if (sku[7] == true) 1666 bcku = bcku | X509KeyUsage.encipherOnly; 1667 if (sku[8] == true) 1668 bcku = bcku | X509KeyUsage.decipherOnly; 1669 return bcku; 1670 } 1671 1672 1677 public static int bitStringToRevokedCertInfo(DERBitString reasonFlags) { 1678 int ret = RevokedCertInfo.REVOKATION_REASON_UNSPECIFIED; 1679 if (reasonFlags == null) { 1680 return ret; 1681 } 1682 int val = reasonFlags.intValue(); 1683 if ( (val & ReasonFlags.aACompromise) != 0) { 1684 ret = RevokedCertInfo.REVOKATION_REASON_AACOMPROMISE; 1685 } 1686 if ( (val & ReasonFlags.affiliationChanged) != 0) { 1687 ret = RevokedCertInfo.REVOKATION_REASON_AFFILIATIONCHANGED; 1688 } 1689 if ( (val & ReasonFlags.cACompromise) != 0) { 1690 ret = RevokedCertInfo.REVOKATION_REASON_CACOMPROMISE; 1691 } 1692 if ( (val & ReasonFlags.certificateHold) != 0) { 1693 ret = RevokedCertInfo.REVOKATION_REASON_CERTIFICATEHOLD; 1694 } 1695 if ( (val & ReasonFlags.cessationOfOperation) != 0) { 1696 ret = RevokedCertInfo.REVOKATION_REASON_CESSATIONOFOPERATION; 1697 } 1698 if ( (val & ReasonFlags.keyCompromise) != 0) { 1699 ret = RevokedCertInfo.REVOKATION_REASON_KEYCOMPROMISE; 1700 } 1701 if ( (val & ReasonFlags.privilegeWithdrawn) != 0) { 1702 ret = RevokedCertInfo.REVOKATION_REASON_PRIVILEGESWITHDRAWN; 1703 } 1704 if ( (val & ReasonFlags.superseded) != 0) { 1705 ret = RevokedCertInfo.REVOKATION_REASON_SUPERSEDED; 1706 } 1707 if ( (val & ReasonFlags.unused) != 0) { 1708 ret = RevokedCertInfo.REVOKATION_REASON_UNSPECIFIED; 1709 } 1710 return ret; 1711 } 1712 1722 public static String insertCNPostfix(String dn, String cnpostfix){ 1723 String newdn = null; 1724 1725 if ((dn != null) && (cnpostfix != null)) { 1726 String o; 1727 X509NameTokenizer xt = new X509NameTokenizer(dn); 1728 boolean alreadyreplaced = false; 1729 while (xt.hasMoreTokens()) { 1730 o = xt.nextToken(); 1731 if (!alreadyreplaced && (o.length() > 3) && 1732 o.substring(0, 3).equalsIgnoreCase("cn=")) { 1733 o += cnpostfix; 1734 alreadyreplaced = true; 1735 } 1736 if(newdn==null){ 1737 newdn=o; 1738 }else{ 1739 newdn += "," + o; 1740 } 1741 } 1742 } 1743 1744 return newdn; 1745 } 1746 1747 1752 private static class BasicX509NameTokenizer 1753 { 1754 private String oid; 1755 private int index; 1756 private StringBuffer buf = new StringBuffer (); 1757 1758 public BasicX509NameTokenizer( 1759 String oid) 1760 { 1761 this.oid = oid; 1762 this.index = -1; 1763 } 1764 1765 public boolean hasMoreTokens() 1766 { 1767 return (index != oid.length()); 1768 } 1769 1770 public String nextToken() 1771 { 1772 if (index == oid.length()) 1773 { 1774 return null; 1775 } 1776 1777 int end = index + 1; 1778 boolean quoted = false; 1779 boolean escaped = false; 1780 1781 buf.setLength(0); 1782 1783 while (end != oid.length()) 1784 { 1785 char c = oid.charAt(end); 1786 1787 if (c == '"') 1788 { 1789 if (!escaped) 1790 { 1791 buf.append(c); 1792 quoted = !quoted; 1793 } 1794 else 1795 { 1796 buf.append(c); 1797 } 1798 escaped = false; 1799 } 1800 else 1801 { 1802 if (escaped || quoted) 1803 { 1804 buf.append(c); 1805 escaped = false; 1806 } 1807 else if (c == '\\') 1808 { 1809 buf.append(c); 1810 escaped = true; 1811 } 1812 else if ( (c == ',') && (!escaped) ) 1813 { 1814 break; 1815 } 1816 else 1817 { 1818 buf.append(c); 1819 } 1820 } 1821 end++; 1822 } 1823 1824 index = end; 1825 return buf.toString().trim(); 1826 } 1827 } 1828 1829 1835 private static Vector getDefaultX509FieldOrder(){ 1836 Vector fieldOrder = new Vector (); 1837 String [] dNObjects = DnComponents.getDnObjects(); 1838 for (int i = 0; i < dNObjects.length; i++) { 1839 fieldOrder.add(DnComponents.getOid(dNObjects[i])); 1840 } 1841 return fieldOrder; 1842 } 1843 1844 1853 private static X509Name getOrderedX509Name( X509Name x509Name, Vector ordering, X509NameEntryConverter converter ){ 1854 1855 if ( ordering == null ){ ordering = new Vector (); } 1857 1858 Vector newOrdering = new Vector (); 1860 Vector newValues = new Vector (); 1861 1862 Hashtable ht = new Hashtable (); 1863 Iterator it = ordering.iterator(); 1864 1865 while( it.hasNext() ){ 1867 DERObjectIdentifier oid = (DERObjectIdentifier) it.next(); 1868 1869 if ( !ht.containsKey(oid) ){ 1870 Vector valueList = getX509NameFields(x509Name, oid); 1871 if ( valueList != null ){ 1873 Iterator itVals = valueList.iterator(); 1874 while( itVals.hasNext() ){ 1875 Object value = itVals.next(); 1876 ht.put(oid, value); 1877 newOrdering.add(oid); 1878 newValues.add(value); 1879 } 1880 } 1881 } } 1884 Vector allOids = x509Name.getOIDs(); 1885 1886 for ( int i=0; i<allOids.size(); i++ ) { 1888 1889 DERObjectIdentifier oid = (DERObjectIdentifier) allOids.get(i); 1890 1891 1892 if ( !ht.containsKey(oid) ){ 1893 Vector valueList = getX509NameFields(x509Name, oid); 1894 1895 if ( valueList != null ){ 1897 Iterator itVals = valueList.iterator(); 1898 1899 while( itVals.hasNext() ){ 1900 Object value = itVals.next(); 1901 ht.put(oid, value); 1902 newOrdering.add(oid); 1903 newValues.add(value); 1904 log.debug("added --> " + oid + " val: " + value); 1905 } 1906 } 1907 } 1908 } 1909 1910 X509Name orderedName = new X509Name(newOrdering, newValues, converter); 1912 1913 return orderedName; 1914 } 1915 1916 1917 1925 private static Vector getX509NameFields( X509Name name, DERObjectIdentifier id ){ 1926 1927 Vector oids = name.getOIDs(); 1928 Vector values = name.getValues(); 1929 Vector vRet = null; 1930 1931 for ( int i=0; i<oids.size(); i++ ){ 1932 1933 if ( id.equals(oids.elementAt(i)) ){ 1934 if ( vRet == null ){ vRet = new Vector (); } 1935 vRet.add(values.get(i)); 1936 } 1937 1938 } 1939 1940 return vRet; 1941 1942 } 1943 1944 1945 1952 private static String getDirectoryStringFromAltName(String altName) { 1953 1954 DNFieldExtractor dnfe = new DNFieldExtractor(altName, DNFieldExtractor.TYPE_SUBJECTALTNAME); 1955 String directoryName = dnfe.getField(DNFieldExtractor.DIRECTORYNAME, 0); 1956 1957 1958 1959 return ( "".equals(directoryName) ? null : directoryName ); 1960 } 1961 1962}
| Popular Tags
|