src/share/classes/sun/security/tools/jarsigner/Main.java

Print this page




  36 import java.text.MessageFormat;
  37 import java.security.cert.Certificate;
  38 import java.security.cert.X509Certificate;
  39 import java.security.cert.CertificateException;
  40 import java.security.*;
  41 import java.lang.reflect.Constructor;
  42 
  43 import com.sun.jarsigner.ContentSigner;
  44 import com.sun.jarsigner.ContentSignerParameters;
  45 import java.net.SocketTimeoutException;
  46 import java.net.URL;
  47 import java.net.URLClassLoader;
  48 import java.security.cert.CertPath;
  49 import java.security.cert.CertPathValidator;
  50 import java.security.cert.CertificateExpiredException;
  51 import java.security.cert.CertificateFactory;
  52 import java.security.cert.CertificateNotYetValidException;
  53 import java.security.cert.PKIXParameters;
  54 import java.security.cert.TrustAnchor;
  55 import java.util.Map.Entry;



  56 import sun.security.tools.KeyStoreUtil;
  57 import sun.security.tools.PathList;
  58 import sun.security.x509.*;
  59 import sun.security.util.*;
  60 import java.util.Base64;
  61 
  62 
  63 /**
  64  * <p>The jarsigner utility.
  65  *
  66  * The exit codes for the main method are:
  67  *
  68  * 0: success
  69  * 1: any error that the jar cannot be signed or verified, including:
  70  *      keystore loading error
  71  *      TSP communication error
  72  *      jarsigner command line error...
  73  * otherwise: error codes from -strict
  74  *
  75  * @author Roland Schemers


  80 
  81     // for i18n
  82     private static final java.util.ResourceBundle rb =
  83         java.util.ResourceBundle.getBundle
  84         ("sun.security.tools.jarsigner.Resources");
  85     private static final Collator collator = Collator.getInstance();
  86     static {
  87         // this is for case insensitive string comparisions
  88         collator.setStrength(Collator.PRIMARY);
  89     }
  90 
  91     private static final String META_INF = "META-INF/";
  92 
  93     private static final Class<?>[] PARAM_STRING = { String.class };
  94 
  95     private static final String NONE = "NONE";
  96     private static final String P11KEYSTORE = "PKCS11";
  97 
  98     private static final long SIX_MONTHS = 180*24*60*60*1000L; //milliseconds
  99 









 100     // Attention:
 101     // This is the entry that get launched by the security tool jarsigner.
 102     public static void main(String args[]) throws Exception {
 103         Main js = new Main();
 104         js.run(args);
 105     }
 106 
 107     static final String VERSION = "1.0";
 108 
 109     static final int IN_KEYSTORE = 0x01;        // signer is in keystore
 110     static final int IN_SCOPE = 0x02;
 111     static final int NOT_ALIAS = 0x04;          // alias list is NOT empty and
 112                                                 // signer is not in alias list
 113     static final int SIGNED_BY_ALIAS = 0x08;    // signer is in alias list
 114 
 115     X509Certificate[] certChain;    // signer's cert chain (when composing)
 116     PrivateKey privateKey;          // private key
 117     KeyStore store;                 // the keystore specified by -keystore
 118                                     // or the default keystore, never null
 119 


 155     private String altSignerClass = null;
 156     private String altSignerClasspath = null;
 157     private ZipFile zipFile = null;
 158 
 159     // Informational warnings
 160     private boolean hasExpiringCert = false;
 161     private boolean noTimestamp = false;
 162     private Date expireDate = new Date(0L);     // used in noTimestamp warning
 163 
 164     // Severe warnings
 165     private boolean hasExpiredCert = false;
 166     private boolean notYetValidCert = false;
 167     private boolean chainNotValidated = false;
 168     private boolean notSignedByAlias = false;
 169     private boolean aliasNotInStore = false;
 170     private boolean hasUnsignedEntry = false;
 171     private boolean badKeyUsage = false;
 172     private boolean badExtendedKeyUsage = false;
 173     private boolean badNetscapeCertType = false;
 174 


 175     CertificateFactory certificateFactory;
 176     CertPathValidator validator;
 177     PKIXParameters pkixParameters;
 178 
 179     public void run(String args[]) {
 180         try {
 181             parseArgs(args);
 182 
 183             // Try to load and install the specified providers
 184             if (providers != null) {
 185                 ClassLoader cl = ClassLoader.getSystemClassLoader();
 186                 Enumeration<String> e = providers.elements();
 187                 while (e.hasMoreElements()) {
 188                     String provName = e.nextElement();
 189                     Class<?> provClass;
 190                     if (cl != null) {
 191                         provClass = cl.loadClass(provName);
 192                     } else {
 193                         provClass = Class.forName(provName);
 194                     }


 560         System.out.println(rb.getString
 561                 (".providerName.name.provider.name"));
 562         System.out.println();
 563         System.out.println(rb.getString
 564                 (".providerClass.class.name.of.cryptographic.service.provider.s"));
 565         System.out.println(rb.getString
 566                 (".providerArg.arg.master.class.file.and.constructor.argument"));
 567         System.out.println();
 568         System.out.println(rb.getString
 569                 (".strict.treat.warnings.as.errors"));
 570         System.out.println();
 571 
 572         System.exit(0);
 573     }
 574 
 575     void verifyJar(String jarName)
 576         throws Exception
 577     {
 578         boolean anySigned = false;  // if there exists entry inside jar signed
 579         JarFile jf = null;




 580 
 581         try {
 582             jf = new JarFile(jarName, true);
 583             Vector<JarEntry> entriesVec = new Vector<>();
 584             byte[] buffer = new byte[8192];
 585 
 586             Enumeration<JarEntry> entries = jf.entries();
 587             while (entries.hasMoreElements()) {
 588                 JarEntry je = entries.nextElement();
 589                 entriesVec.addElement(je);
 590                 InputStream is = null;





 591                 try {
 592                     is = jf.getInputStream(je);
 593                     int n;
 594                     while ((n = is.read(buffer, 0, buffer.length)) != -1) {

























 595                         // we just read. this will throw a SecurityException
 596                         // if  a signature/digest check fails.
 597                     }
 598                 } finally {
 599                     if (is != null) {
 600                         is.close();
 601                     }
 602                 }
 603             }
 604 
 605             Manifest man = jf.getManifest();
 606             boolean hasSignature = false;
 607 
 608             // The map to record display info, only used when -verbose provided
 609             //      key: signer info string
 610             //      value: the list of files with common key
 611             Map<String,List<String>> output = new LinkedHashMap<>();
 612 
 613             if (man != null) {
 614                 if (verbose != null) System.out.println();
 615                 Enumeration<JarEntry> e = entriesVec.elements();
 616 
 617                 String tab = rb.getString("6SPACE");
 618 
 619                 while (e.hasMoreElements()) {
 620                     JarEntry je = e.nextElement();


 739                             } else {
 740                                 System.out.println(files.get(0));
 741                             }
 742                         }
 743                         System.out.printf(key.substring(pipe+1));
 744                     }
 745                 }
 746                 System.out.println();
 747                 System.out.println(rb.getString(
 748                     ".s.signature.was.verified."));
 749                 System.out.println(rb.getString(
 750                     ".m.entry.is.listed.in.manifest"));
 751                 System.out.println(rb.getString(
 752                     ".k.at.least.one.certificate.was.found.in.keystore"));
 753                 System.out.println(rb.getString(
 754                     ".i.at.least.one.certificate.was.found.in.identity.scope"));
 755                 if (ckaliases.size() > 0) {
 756                     System.out.println(rb.getString(
 757                         ".X.not.signed.by.specified.alias.es."));
 758                 }
 759                 System.out.println();
 760             }
 761             if (man == null)

 762                 System.out.println(rb.getString("no.manifest."));

 763 



















































































 764             if (!anySigned) {
 765                 if (hasSignature) {









 766                     System.out.println(rb.getString("jar.treated.unsigned"));
 767                 } else {
 768                     System.out.println(rb.getString("jar.is.unsigned"));
 769                 }
 770             } else {
 771                 boolean warningAppeared = false;
 772                 boolean errorAppeared = false;
 773                 if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
 774                         notYetValidCert || chainNotValidated || hasExpiredCert ||
 775                         hasUnsignedEntry ||
 776                         aliasNotInStore || notSignedByAlias) {
 777 
 778                     if (strict) {
 779                         System.out.println(rb.getString("jar.verified.with.signer.errors."));
 780                         System.out.println();
 781                         System.out.println(rb.getString("Error."));
 782                         errorAppeared = true;
 783                     } else {
 784                         System.out.println(rb.getString("jar.verified."));
 785                         System.out.println();


 852                         System.out.println(rb.getString(
 853                                 "Re.run.with.the.verbose.and.certs.options.for.more.details."));
 854                     }
 855                 }
 856             }
 857             return;
 858         } catch (Exception e) {
 859             System.out.println(rb.getString("jarsigner.") + e);
 860             if (debug) {
 861                 e.printStackTrace();
 862             }
 863         } finally { // close the resource
 864             if (jf != null) {
 865                 jf.close();
 866             }
 867         }
 868 
 869         System.exit(1);
 870     }
 871 




















 872     private static MessageFormat validityTimeForm = null;
 873     private static MessageFormat notYetTimeForm = null;
 874     private static MessageFormat expiredTimeForm = null;
 875     private static MessageFormat expiringTimeForm = null;
 876 
 877     /*
 878      * Display some details about a certificate:
 879      *
 880      * [<tab>] <cert-type> [", " <subject-DN>] [" (" <keystore-entry-alias> ")"]
 881      * [<validity-period> | <expiry-warning>]
 882      *
 883      * Note: no newline character at the end
 884      */
 885     String printCert(String tab, Certificate c, boolean checkValidityPeriod,
 886         Date timestamp, boolean checkUsage) {
 887 
 888         StringBuilder certStr = new StringBuilder();
 889         String space = rb.getString("SPACE");
 890         X509Certificate x509Cert = null;
 891 




  36 import java.text.MessageFormat;
  37 import java.security.cert.Certificate;
  38 import java.security.cert.X509Certificate;
  39 import java.security.cert.CertificateException;
  40 import java.security.*;
  41 import java.lang.reflect.Constructor;
  42 
  43 import com.sun.jarsigner.ContentSigner;
  44 import com.sun.jarsigner.ContentSignerParameters;
  45 import java.net.SocketTimeoutException;
  46 import java.net.URL;
  47 import java.net.URLClassLoader;
  48 import java.security.cert.CertPath;
  49 import java.security.cert.CertPathValidator;
  50 import java.security.cert.CertificateExpiredException;
  51 import java.security.cert.CertificateFactory;
  52 import java.security.cert.CertificateNotYetValidException;
  53 import java.security.cert.PKIXParameters;
  54 import java.security.cert.TrustAnchor;
  55 import java.util.Map.Entry;
  56 import sun.security.pkcs.PKCS7;
  57 import sun.security.pkcs.SignerInfo;
  58 import sun.security.timestamp.TimestampToken;
  59 import sun.security.tools.KeyStoreUtil;
  60 import sun.security.tools.PathList;
  61 import sun.security.x509.*;
  62 import sun.security.util.*;
  63 import java.util.Base64;
  64 
  65 
  66 /**
  67  * <p>The jarsigner utility.
  68  *
  69  * The exit codes for the main method are:
  70  *
  71  * 0: success
  72  * 1: any error that the jar cannot be signed or verified, including:
  73  *      keystore loading error
  74  *      TSP communication error
  75  *      jarsigner command line error...
  76  * otherwise: error codes from -strict
  77  *
  78  * @author Roland Schemers


  83 
  84     // for i18n
  85     private static final java.util.ResourceBundle rb =
  86         java.util.ResourceBundle.getBundle
  87         ("sun.security.tools.jarsigner.Resources");
  88     private static final Collator collator = Collator.getInstance();
  89     static {
  90         // this is for case insensitive string comparisions
  91         collator.setStrength(Collator.PRIMARY);
  92     }
  93 
  94     private static final String META_INF = "META-INF/";
  95 
  96     private static final Class<?>[] PARAM_STRING = { String.class };
  97 
  98     private static final String NONE = "NONE";
  99     private static final String P11KEYSTORE = "PKCS11";
 100 
 101     private static final long SIX_MONTHS = 180*24*60*60*1000L; //milliseconds
 102 
 103     private static final DisabledAlgorithmConstraints DISABLED_CHECK =
 104             new DisabledAlgorithmConstraints(
 105                     DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
 106 
 107     private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = Collections
 108             .unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
 109     private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
 110             .unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
 111 
 112     // Attention:
 113     // This is the entry that get launched by the security tool jarsigner.
 114     public static void main(String args[]) throws Exception {
 115         Main js = new Main();
 116         js.run(args);
 117     }
 118 
 119     static final String VERSION = "1.0";
 120 
 121     static final int IN_KEYSTORE = 0x01;        // signer is in keystore
 122     static final int IN_SCOPE = 0x02;
 123     static final int NOT_ALIAS = 0x04;          // alias list is NOT empty and
 124                                                 // signer is not in alias list
 125     static final int SIGNED_BY_ALIAS = 0x08;    // signer is in alias list
 126 
 127     X509Certificate[] certChain;    // signer's cert chain (when composing)
 128     PrivateKey privateKey;          // private key
 129     KeyStore store;                 // the keystore specified by -keystore
 130                                     // or the default keystore, never null
 131 


 167     private String altSignerClass = null;
 168     private String altSignerClasspath = null;
 169     private ZipFile zipFile = null;
 170 
 171     // Informational warnings
 172     private boolean hasExpiringCert = false;
 173     private boolean noTimestamp = false;
 174     private Date expireDate = new Date(0L);     // used in noTimestamp warning
 175 
 176     // Severe warnings
 177     private boolean hasExpiredCert = false;
 178     private boolean notYetValidCert = false;
 179     private boolean chainNotValidated = false;
 180     private boolean notSignedByAlias = false;
 181     private boolean aliasNotInStore = false;
 182     private boolean hasUnsignedEntry = false;
 183     private boolean badKeyUsage = false;
 184     private boolean badExtendedKeyUsage = false;
 185     private boolean badNetscapeCertType = false;
 186 
 187     private boolean seeWeak = false;
 188 
 189     CertificateFactory certificateFactory;
 190     CertPathValidator validator;
 191     PKIXParameters pkixParameters;
 192 
 193     public void run(String args[]) {
 194         try {
 195             parseArgs(args);
 196 
 197             // Try to load and install the specified providers
 198             if (providers != null) {
 199                 ClassLoader cl = ClassLoader.getSystemClassLoader();
 200                 Enumeration<String> e = providers.elements();
 201                 while (e.hasMoreElements()) {
 202                     String provName = e.nextElement();
 203                     Class<?> provClass;
 204                     if (cl != null) {
 205                         provClass = cl.loadClass(provName);
 206                     } else {
 207                         provClass = Class.forName(provName);
 208                     }


 574         System.out.println(rb.getString
 575                 (".providerName.name.provider.name"));
 576         System.out.println();
 577         System.out.println(rb.getString
 578                 (".providerClass.class.name.of.cryptographic.service.provider.s"));
 579         System.out.println(rb.getString
 580                 (".providerArg.arg.master.class.file.and.constructor.argument"));
 581         System.out.println();
 582         System.out.println(rb.getString
 583                 (".strict.treat.warnings.as.errors"));
 584         System.out.println();
 585 
 586         System.exit(0);
 587     }
 588 
 589     void verifyJar(String jarName)
 590         throws Exception
 591     {
 592         boolean anySigned = false;  // if there exists entry inside jar signed
 593         JarFile jf = null;
 594         Map<String,String> digestMap = new HashMap<>();
 595         Map<String,PKCS7> sigMap = new HashMap<>();
 596         Map<String,String> sigNameMap = new HashMap<>();
 597         Map<String,String> unparsableSignatures = new HashMap<>();
 598 
 599         try {
 600             jf = new JarFile(jarName, true);
 601             Vector<JarEntry> entriesVec = new Vector<>();
 602             byte[] buffer = new byte[8192];
 603 
 604             Enumeration<JarEntry> entries = jf.entries();
 605             while (entries.hasMoreElements()) {
 606                 JarEntry je = entries.nextElement();
 607                 entriesVec.addElement(je);
 608                 try (InputStream is = jf.getInputStream(je)) {
 609                     String name = je.getName();
 610                     if (signatureRelated(name)
 611                             && SignatureFileVerifier.isBlockOrSF(name)) {
 612                         String alias = name.substring(name.lastIndexOf('/') + 1,
 613                                 name.lastIndexOf('.'));
 614                 try {
 615                             if (name.endsWith(".SF")) {
 616                                 Manifest sf = new Manifest(is);
 617                                 boolean found = false;
 618                                 for (Object obj : sf.getMainAttributes().keySet()) {
 619                                     String key = obj.toString();
 620                                     if (key.endsWith("-Digest-Manifest")) {
 621                                         digestMap.put(alias,
 622                                                 key.substring(0, key.length() - 16));
 623                                         found = true;
 624                                         break;
 625                                     }
 626                                 }
 627                                 if (!found) {
 628                                     unparsableSignatures.putIfAbsent(alias,
 629                                         String.format(
 630                                             rb.getString("history.unparsable"),
 631                                             name));
 632                                 }
 633                             } else {
 634                                 sigNameMap.put(alias, name);
 635                                 sigMap.put(alias, new PKCS7(is));
 636                             }
 637                         } catch (IOException ioe) {
 638                             unparsableSignatures.putIfAbsent(alias, String.format(
 639                                     rb.getString("history.unparsable"), name));
 640                         }
 641                     } else {
 642                         while (is.read(buffer, 0, buffer.length) != -1) {
 643                         // we just read. this will throw a SecurityException
 644                         // if  a signature/digest check fails.
 645                     }



 646                     }
 647                 }
 648             }
 649 
 650             Manifest man = jf.getManifest();
 651             boolean hasSignature = false;
 652 
 653             // The map to record display info, only used when -verbose provided
 654             //      key: signer info string
 655             //      value: the list of files with common key
 656             Map<String,List<String>> output = new LinkedHashMap<>();
 657 
 658             if (man != null) {
 659                 if (verbose != null) System.out.println();
 660                 Enumeration<JarEntry> e = entriesVec.elements();
 661 
 662                 String tab = rb.getString("6SPACE");
 663 
 664                 while (e.hasMoreElements()) {
 665                     JarEntry je = e.nextElement();


 784                             } else {
 785                                 System.out.println(files.get(0));
 786                             }
 787                         }
 788                         System.out.printf(key.substring(pipe+1));
 789                     }
 790                 }
 791                 System.out.println();
 792                 System.out.println(rb.getString(
 793                     ".s.signature.was.verified."));
 794                 System.out.println(rb.getString(
 795                     ".m.entry.is.listed.in.manifest"));
 796                 System.out.println(rb.getString(
 797                     ".k.at.least.one.certificate.was.found.in.keystore"));
 798                 System.out.println(rb.getString(
 799                     ".i.at.least.one.certificate.was.found.in.identity.scope"));
 800                 if (ckaliases.size() > 0) {
 801                     System.out.println(rb.getString(
 802                         ".X.not.signed.by.specified.alias.es."));
 803                 }

 804             }
 805             if (man == null) {
 806                 System.out.println();
 807                 System.out.println(rb.getString("no.manifest."));
 808             }
 809 
 810             // Even if the verbose option is not specified, all out strings
 811             // must be generated so seeWeak can be updated.
 812             if (!digestMap.isEmpty()
 813                     || !sigMap.isEmpty()
 814                     || !unparsableSignatures.isEmpty()) {
 815                 if (verbose != null) {
 816                 System.out.println();
 817             }
 818                 for (String s : sigMap.keySet()) {
 819                     if (!digestMap.containsKey(s)) {
 820                         unparsableSignatures.putIfAbsent(s, String.format(
 821                                 rb.getString("history.nosf"), s));
 822                     }
 823                 }
 824                 for (String s : digestMap.keySet()) {
 825                     PKCS7 p7 = sigMap.get(s);
 826                     if (p7 != null) {
 827                         String history;
 828                         try {
 829                             SignerInfo si = p7.getSignerInfos()[0];
 830                             X509Certificate signer = si.getCertificate(p7);
 831                             String digestAlg = digestMap.get(s);
 832                             String sigAlg = AlgorithmId.makeSigAlg(
 833                                     si.getDigestAlgorithmId().getName(),
 834                                     si.getDigestEncryptionAlgorithmId().getName());
 835                             PublicKey key = signer.getPublicKey();
 836                             PKCS7 tsToken = si.getTsToken();
 837                             if (tsToken != null) {
 838                                 SignerInfo tsSi = tsToken.getSignerInfos()[0];
 839                                 X509Certificate tsSigner = tsSi.getCertificate(tsToken);
 840                                 byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
 841                                 TimestampToken tsTokenInfo = new TimestampToken(encTsTokenInfo);
 842                                 PublicKey tsKey = tsSigner.getPublicKey();
 843                                 String tsDigestAlg = tsTokenInfo.getHashAlgorithm().getName();
 844                                 String tsSigAlg = AlgorithmId.makeSigAlg(
 845                                         tsSi.getDigestAlgorithmId().getName(),
 846                                         tsSi.getDigestEncryptionAlgorithmId().getName());
 847                                 Calendar c = Calendar.getInstance(
 848                                         TimeZone.getTimeZone("UTC"),
 849                                         Locale.getDefault(Locale.Category.FORMAT));
 850                                 c.setTime(tsTokenInfo.getDate());
 851                                 history = String.format(
 852                                         rb.getString("history.with.ts"),
 853                                         signer.getSubjectX500Principal(),
 854                                         withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
 855                                         withWeak(sigAlg, SIG_PRIMITIVE_SET),
 856                                         withWeak(key),
 857                                         c,
 858                                         tsSigner.getSubjectX500Principal(),
 859                                         withWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET),
 860                                         withWeak(tsSigAlg, SIG_PRIMITIVE_SET),
 861                                         withWeak(tsKey));
 862                             } else {
 863                                 history = String.format(
 864                                         rb.getString("history.without.ts"),
 865                                         signer.getSubjectX500Principal(),
 866                                         withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
 867                                         withWeak(sigAlg, SIG_PRIMITIVE_SET),
 868                                         withWeak(key));
 869                             }
 870                         } catch (Exception e) {
 871                             // The only usage of sigNameMap, remember the name
 872                             // of the block file if it's invalid.
 873                             history = String.format(
 874                                     rb.getString("history.unparsable"),
 875                                     sigNameMap.get(s));
 876                         }
 877                         if (verbose != null) {
 878                             System.out.println(history);
 879                         }
 880                     } else {
 881                         unparsableSignatures.putIfAbsent(s, String.format(
 882                                 rb.getString("history.nobk"), s));
 883                     }
 884                 }
 885                 if (verbose != null) {
 886                     for (String s : unparsableSignatures.keySet()) {
 887                         System.out.println(unparsableSignatures.get(s));
 888                     }
 889                 }
 890             }
 891             System.out.println();
 892 
 893             if (!anySigned) {
 894                 if (seeWeak) {
 895                     if (verbose != null) {
 896                         System.out.println(rb.getString("jar.treated.unsigned.see.weak.verbose"));
 897                         System.out.println("\n  " +
 898                                 DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS +
 899                                 "=" + Security.getProperty(DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS));
 900                     } else {
 901                         System.out.println(rb.getString("jar.treated.unsigned.see.weak"));
 902                     }
 903                 } else if (hasSignature) {
 904                     System.out.println(rb.getString("jar.treated.unsigned"));
 905                 } else {
 906                     System.out.println(rb.getString("jar.is.unsigned"));
 907                 }
 908             } else {
 909                 boolean warningAppeared = false;
 910                 boolean errorAppeared = false;
 911                 if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
 912                         notYetValidCert || chainNotValidated || hasExpiredCert ||
 913                         hasUnsignedEntry ||
 914                         aliasNotInStore || notSignedByAlias) {
 915 
 916                     if (strict) {
 917                         System.out.println(rb.getString("jar.verified.with.signer.errors."));
 918                         System.out.println();
 919                         System.out.println(rb.getString("Error."));
 920                         errorAppeared = true;
 921                     } else {
 922                         System.out.println(rb.getString("jar.verified."));
 923                         System.out.println();


 990                         System.out.println(rb.getString(
 991                                 "Re.run.with.the.verbose.and.certs.options.for.more.details."));
 992                     }
 993                 }
 994             }
 995             return;
 996         } catch (Exception e) {
 997             System.out.println(rb.getString("jarsigner.") + e);
 998             if (debug) {
 999                 e.printStackTrace();
1000             }
1001         } finally { // close the resource
1002             if (jf != null) {
1003                 jf.close();
1004             }
1005         }
1006 
1007         System.exit(1);
1008     }
1009 
1010     private String withWeak(String alg, Set<CryptoPrimitive> primitiveSet) {
1011         if (DISABLED_CHECK.permits(primitiveSet, alg, null)) {
1012             return alg;
1013         } else {
1014             seeWeak = true;
1015             return String.format(rb.getString("with.weak"), alg);
1016         }
1017     }
1018 
1019     private String withWeak(PublicKey key) {
1020         if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
1021             return String.format(
1022                     rb.getString("key.bit"), KeyUtil.getKeySize(key));
1023         } else {
1024             seeWeak = true;
1025             return String.format(
1026                     rb.getString("key.bit.weak"), KeyUtil.getKeySize(key));
1027         }
1028     }
1029 
1030     private static MessageFormat validityTimeForm = null;
1031     private static MessageFormat notYetTimeForm = null;
1032     private static MessageFormat expiredTimeForm = null;
1033     private static MessageFormat expiringTimeForm = null;
1034 
1035     /*
1036      * Display some details about a certificate:
1037      *
1038      * [<tab>] <cert-type> [", " <subject-DN>] [" (" <keystore-entry-alias> ")"]
1039      * [<validity-period> | <expiry-warning>]
1040      *
1041      * Note: no newline character at the end
1042      */
1043     String printCert(String tab, Certificate c, boolean checkValidityPeriod,
1044         Date timestamp, boolean checkUsage) {
1045 
1046         StringBuilder certStr = new StringBuilder();
1047         String space = rb.getString("SPACE");
1048         X509Certificate x509Cert = null;
1049