< prev index next >

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

Print this page
rev 15874 : 8163304: jarsigner -verbose -verify should print the algorithms used to sign the jar


  33 import java.text.Collator;
  34 import java.text.MessageFormat;
  35 import java.security.cert.Certificate;
  36 import java.security.cert.X509Certificate;
  37 import java.security.cert.CertificateException;
  38 import java.security.*;
  39 
  40 import java.net.SocketTimeoutException;
  41 import java.net.URL;
  42 import java.security.cert.CertPath;
  43 import java.security.cert.CertPathValidator;
  44 import java.security.cert.CertificateExpiredException;
  45 import java.security.cert.CertificateFactory;
  46 import java.security.cert.CertificateNotYetValidException;
  47 import java.security.cert.PKIXParameters;
  48 import java.security.cert.TrustAnchor;
  49 import java.util.Map.Entry;
  50 
  51 import jdk.security.jarsigner.JarSigner;
  52 import jdk.security.jarsigner.JarSignerException;



  53 import sun.security.tools.KeyStoreUtil;
  54 import sun.security.x509.*;
  55 import sun.security.util.*;
  56 
  57 
  58 /**
  59  * <p>The jarsigner utility.
  60  *
  61  * The exit codes for the main method are:
  62  *
  63  * 0: success
  64  * 1: any error that the jar cannot be signed or verified, including:
  65  *      keystore loading error
  66  *      TSP communication error
  67  *      jarsigner command line error...
  68  * otherwise: error codes from -strict
  69  *
  70  * @author Roland Schemers
  71  * @author Jan Luehe
  72  */
  73 public class Main {
  74 
  75     // for i18n
  76     private static final java.util.ResourceBundle rb =
  77         java.util.ResourceBundle.getBundle
  78         ("sun.security.tools.jarsigner.Resources");
  79     private static final Collator collator = Collator.getInstance();
  80     static {
  81         // this is for case insensitive string comparisions
  82         collator.setStrength(Collator.PRIMARY);
  83     }
  84 
  85     private static final String NONE = "NONE";
  86     private static final String P11KEYSTORE = "PKCS11";
  87 
  88     private static final long SIX_MONTHS = 180*24*60*60*1000L; //milliseconds
  89 









  90     // Attention:
  91     // This is the entry that get launched by the security tool jarsigner.
  92     public static void main(String args[]) throws Exception {
  93         Main js = new Main();
  94         js.run(args);
  95     }
  96 
  97     static final String VERSION = "1.0";
  98 
  99     static final int IN_KEYSTORE = 0x01;        // signer is in keystore
 100     static final int NOT_ALIAS = 0x04;          // alias list is NOT empty and
 101                                                 // signer is not in alias list
 102     static final int SIGNED_BY_ALIAS = 0x08;    // signer is in alias list
 103 
 104     X509Certificate[] certChain;    // signer's cert chain (when composing)
 105     PrivateKey privateKey;          // private key
 106     KeyStore store;                 // the keystore specified by -keystore
 107                                     // or the default keystore, never null
 108 
 109     String keystore; // key store file


 146     // Informational warnings
 147     private boolean hasExpiringCert = false;
 148     private boolean noTimestamp = false;
 149     private Date expireDate = new Date(0L);     // used in noTimestamp warning
 150 
 151     // Severe warnings
 152     private int weakAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg
 153     private boolean hasExpiredCert = false;
 154     private boolean notYetValidCert = false;
 155     private boolean chainNotValidated = false;
 156     private boolean notSignedByAlias = false;
 157     private boolean aliasNotInStore = false;
 158     private boolean hasUnsignedEntry = false;
 159     private boolean badKeyUsage = false;
 160     private boolean badExtendedKeyUsage = false;
 161     private boolean badNetscapeCertType = false;
 162     private boolean signerSelfSigned = false;
 163 
 164     private Throwable chainNotValidatedReason = null;
 165 


 166     CertificateFactory certificateFactory;
 167     CertPathValidator validator;
 168     PKIXParameters pkixParameters;
 169 
 170     public void run(String args[]) {
 171         try {
 172             args = parseArgs(args);
 173 
 174             // Try to load and install the specified providers
 175             if (providers != null) {
 176                 for (String provName: providers) {
 177                     try {
 178                         KeyStoreUtil.loadProviderByName(provName,
 179                                 providerArgs.get(provName));
 180                         if (debug) {
 181                             System.out.println("loadProviderByName: " + provName);
 182                         }
 183                     } catch (IllegalArgumentException e) {
 184                         throw new Exception(String.format(rb.getString(
 185                                 "provider.name.not.found"), provName));


 611         System.out.println(rb.getString
 612                 (".providerClass.option"));
 613         System.out.println(rb.getString
 614                 (".providerArg.option.2"));
 615         System.out.println();
 616         System.out.println(rb.getString
 617                 (".strict.treat.warnings.as.errors"));
 618         System.out.println();
 619         System.out.println(rb.getString
 620                 (".conf.url.specify.a.pre.configured.options.file"));
 621         System.out.println();
 622 
 623         System.exit(0);
 624     }
 625 
 626     void verifyJar(String jarName)
 627         throws Exception
 628     {
 629         boolean anySigned = false;  // if there exists entry inside jar signed
 630         JarFile jf = null;




 631 
 632         try {
 633             jf = new JarFile(jarName, true);
 634             Vector<JarEntry> entriesVec = new Vector<>();
 635             byte[] buffer = new byte[8192];
 636 
 637             Enumeration<JarEntry> entries = jf.entries();
 638             while (entries.hasMoreElements()) {
 639                 JarEntry je = entries.nextElement();
 640                 entriesVec.addElement(je);
 641                 InputStream is = null;
 642                 try {
 643                     is = jf.getInputStream(je);































 644                     while (is.read(buffer, 0, buffer.length) != -1) {
 645                         // we just read. this will throw a SecurityException
 646                         // if  a signature/digest check fails.
 647                     }
 648                 } finally {
 649                     if (is != null) {
 650                         is.close();
 651                     }
 652                 }
 653             }
 654 
 655             Manifest man = jf.getManifest();
 656             boolean hasSignature = false;
 657 
 658             // The map to record display info, only used when -verbose provided
 659             //      key: signer info string
 660             //      value: the list of files with common key
 661             Map<String,List<String>> output = new LinkedHashMap<>();
 662 
 663             if (man != null) {
 664                 if (verbose != null) System.out.println();
 665                 Enumeration<JarEntry> e = entriesVec.elements();
 666 
 667                 String tab = rb.getString("6SPACE");
 668 
 669                 while (e.hasMoreElements()) {
 670                     JarEntry je = e.nextElement();


 788                                         String.format(rb.getString(
 789                                         ".and.d.more."), files.size()-1));
 790                             } else {
 791                                 System.out.println(files.get(0));
 792                             }
 793                         }
 794                         System.out.printf(key.substring(pipe+1));
 795                     }
 796                 }
 797                 System.out.println();
 798                 System.out.println(rb.getString(
 799                     ".s.signature.was.verified."));
 800                 System.out.println(rb.getString(
 801                     ".m.entry.is.listed.in.manifest"));
 802                 System.out.println(rb.getString(
 803                     ".k.at.least.one.certificate.was.found.in.keystore"));
 804                 if (ckaliases.size() > 0) {
 805                     System.out.println(rb.getString(
 806                         ".X.not.signed.by.specified.alias.es."));
 807                 }
 808                 System.out.println();
 809             }
 810             if (man == null)

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

 812 
 813             // If signer is a trusted cert or private entry in user's own
 814             // keystore, it can be self-signed.
 815             if (!aliasNotInStore) {
 816                 signerSelfSigned = false;
 817             }
 818 


















































































 819             if (!anySigned) {
 820                 if (hasSignature) {









 821                     System.out.println(rb.getString("jar.treated.unsigned"));
 822                 } else {
 823                     System.out.println(rb.getString("jar.is.unsigned"));
 824                 }
 825             } else {
 826                 boolean warningAppeared = false;
 827                 boolean errorAppeared = false;
 828                 if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
 829                         notYetValidCert || chainNotValidated || hasExpiredCert ||
 830                         hasUnsignedEntry || signerSelfSigned || (weakAlg != 0) ||
 831                         aliasNotInStore || notSignedByAlias) {
 832 
 833                     if (strict) {
 834                         System.out.println(rb.getString("jar.verified.with.signer.errors."));
 835                         System.out.println();
 836                         System.out.println(rb.getString("Error."));
 837                         errorAppeared = true;
 838                     } else {
 839                         System.out.println(rb.getString("jar.verified."));
 840                         System.out.println();
 841                         System.out.println(rb.getString("Warning."));
 842                         warningAppeared = true;
 843                     }
 844 
 845                     if (weakAlg != 0) {
 846                         // In fact, jarsigner verification did not catch this
 847                         // since it has not read the JarFile content itself.
 848                         // Everything is done with JarFile API.


 849                     }
 850 
 851                     if (badKeyUsage) {
 852                         System.out.println(
 853                             rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
 854                     }
 855 
 856                     if (badExtendedKeyUsage) {
 857                         System.out.println(
 858                             rb.getString("This.jar.contains.entries.whose.signer.certificate.s.ExtendedKeyUsage.extension.doesn.t.allow.code.signing."));
 859                     }
 860 
 861                     if (badNetscapeCertType) {
 862                         System.out.println(
 863                             rb.getString("This.jar.contains.entries.whose.signer.certificate.s.NetscapeCertType.extension.doesn.t.allow.code.signing."));
 864                     }
 865 
 866                     if (hasUnsignedEntry) {
 867                         System.out.println(rb.getString(
 868                             "This.jar.contains.unsigned.entries.which.have.not.been.integrity.checked."));


 919                         System.out.println(rb.getString(
 920                                 "Re.run.with.the.verbose.and.certs.options.for.more.details."));
 921                     }
 922                 }
 923             }
 924             return;
 925         } catch (Exception e) {
 926             System.out.println(rb.getString("jarsigner.") + e);
 927             if (debug) {
 928                 e.printStackTrace();
 929             }
 930         } finally { // close the resource
 931             if (jf != null) {
 932                 jf.close();
 933             }
 934         }
 935 
 936         System.exit(1);
 937     }
 938 




















 939     private static MessageFormat validityTimeForm = null;
 940     private static MessageFormat notYetTimeForm = null;
 941     private static MessageFormat expiredTimeForm = null;
 942     private static MessageFormat expiringTimeForm = null;
 943 
 944     /*
 945      * Display some details about a certificate:
 946      *
 947      * [<tab>] <cert-type> [", " <subject-DN>] [" (" <keystore-entry-alias> ")"]
 948      * [<validity-period> | <expiry-warning>]
 949      *
 950      * Note: no newline character at the end
 951      */
 952     String printCert(String tab, Certificate c, boolean checkValidityPeriod,
 953         Date timestamp, boolean checkUsage) {
 954 
 955         StringBuilder certStr = new StringBuilder();
 956         String space = rb.getString("SPACE");
 957         X509Certificate x509Cert = null;
 958 


1108     int inKeyStore(CodeSigner[] signers) {
1109 
1110         if (signers == null)
1111             return 0;
1112 
1113         int output = 0;
1114 
1115         for (CodeSigner signer: signers) {
1116             int result = inKeyStoreForOneSigner(signer);
1117             output |= result;
1118         }
1119         if (ckaliases.size() > 0 && (output & SIGNED_BY_ALIAS) == 0) {
1120             output |= NOT_ALIAS;
1121         }
1122         return output;
1123     }
1124 
1125     void signJar(String jarName, String alias)
1126             throws Exception {
1127 
1128         DisabledAlgorithmConstraints dac =
1129                 new DisabledAlgorithmConstraints(
1130                         DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
1131 
1132         if (digestalg != null && !dac.permits(
1133                 Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), digestalg, null)) {
1134             weakAlg |= 1;
1135         }
1136         if (tSADigestAlg != null && !dac.permits(
1137                 Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), tSADigestAlg, null)) {
1138             weakAlg |= 4;
1139         }
1140         if (sigalg != null && !dac.permits(
1141                 Collections.singleton(CryptoPrimitive.SIGNATURE), sigalg, null)) {
1142             weakAlg |= 2;
1143         }




1144 
1145         boolean aliasUsed = false;
1146         X509Certificate tsaCert = null;
1147 
1148         if (sigfile == null) {
1149             sigfile = alias;
1150             aliasUsed = true;
1151         }
1152 
1153         if (sigfile.length() > 8) {
1154             sigfile = sigfile.substring(0, 8).toUpperCase(Locale.ENGLISH);
1155         } else {
1156             sigfile = sigfile.toUpperCase(Locale.ENGLISH);
1157         }
1158 
1159         StringBuilder tmpSigFile = new StringBuilder(sigfile.length());
1160         for (int j = 0; j < sigfile.length(); j++) {
1161             char c = sigfile.charAt(j);
1162             if (!
1163                     ((c>= 'A' && c<= 'Z') ||


1368                     System.out.println(
1369                             rb.getString("The.signer.s.certificate.is.self.signed."));
1370                 }
1371 
1372                 if ((weakAlg & 1) == 1) {
1373                     System.out.println(String.format(
1374                             rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
1375                             digestalg, "-digestalg"));
1376                 }
1377 
1378                 if ((weakAlg & 2) == 2) {
1379                     System.out.println(String.format(
1380                             rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
1381                             sigalg, "-sigalg"));
1382                 }
1383                 if ((weakAlg & 4) == 4) {
1384                     System.out.println(String.format(
1385                             rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
1386                             tSADigestAlg, "-tsadigestalg"));
1387                 }





1388             } else {
1389                 System.out.println(rb.getString("jar.signed."));
1390             }
1391             if (hasExpiringCert || noTimestamp) {
1392                 if (!warningAppeared) {
1393                     System.out.println();
1394                     System.out.println(rb.getString("Warning."));
1395                 }
1396 
1397                 if (hasExpiringCert) {
1398                     System.out.println(
1399                             rb.getString("The.signer.certificate.will.expire.within.six.months."));
1400                 }
1401 
1402                 if (noTimestamp) {
1403                     System.out.println(
1404                             String.format(rb.getString("no.timestamp.signing"), expireDate));
1405                 }
1406             }
1407 




  33 import java.text.Collator;
  34 import java.text.MessageFormat;
  35 import java.security.cert.Certificate;
  36 import java.security.cert.X509Certificate;
  37 import java.security.cert.CertificateException;
  38 import java.security.*;
  39 
  40 import java.net.SocketTimeoutException;
  41 import java.net.URL;
  42 import java.security.cert.CertPath;
  43 import java.security.cert.CertPathValidator;
  44 import java.security.cert.CertificateExpiredException;
  45 import java.security.cert.CertificateFactory;
  46 import java.security.cert.CertificateNotYetValidException;
  47 import java.security.cert.PKIXParameters;
  48 import java.security.cert.TrustAnchor;
  49 import java.util.Map.Entry;
  50 
  51 import jdk.security.jarsigner.JarSigner;
  52 import jdk.security.jarsigner.JarSignerException;
  53 import sun.security.pkcs.PKCS7;
  54 import sun.security.pkcs.SignerInfo;
  55 import sun.security.timestamp.TimestampToken;
  56 import sun.security.tools.KeyStoreUtil;
  57 import sun.security.x509.*;
  58 import sun.security.util.*;
  59 
  60 
  61 /**
  62  * <p>The jarsigner utility.
  63  *
  64  * The exit codes for the main method are:
  65  *
  66  * 0: success
  67  * 1: any error that the jar cannot be signed or verified, including:
  68  *      keystore loading error
  69  *      TSP communication error
  70  *      jarsigner command line error...
  71  * otherwise: error codes from -strict
  72  *
  73  * @author Roland Schemers
  74  * @author Jan Luehe
  75  */
  76 public class Main {
  77 
  78     // for i18n
  79     private static final java.util.ResourceBundle rb =
  80         java.util.ResourceBundle.getBundle
  81         ("sun.security.tools.jarsigner.Resources");
  82     private static final Collator collator = Collator.getInstance();
  83     static {
  84         // this is for case insensitive string comparisions
  85         collator.setStrength(Collator.PRIMARY);
  86     }
  87 
  88     private static final String NONE = "NONE";
  89     private static final String P11KEYSTORE = "PKCS11";
  90 
  91     private static final long SIX_MONTHS = 180*24*60*60*1000L; //milliseconds
  92 
  93     private static final DisabledAlgorithmConstraints DISABLED_CHECK =
  94             new DisabledAlgorithmConstraints(
  95                     DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
  96 
  97     private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = Collections
  98             .unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
  99     private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
 100             .unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
 101 
 102     // Attention:
 103     // This is the entry that get launched by the security tool jarsigner.
 104     public static void main(String args[]) throws Exception {
 105         Main js = new Main();
 106         js.run(args);
 107     }
 108 
 109     static final String VERSION = "1.0";
 110 
 111     static final int IN_KEYSTORE = 0x01;        // signer is in keystore
 112     static final int NOT_ALIAS = 0x04;          // alias list is NOT empty and
 113                                                 // signer is not in alias list
 114     static final int SIGNED_BY_ALIAS = 0x08;    // signer is in alias list
 115 
 116     X509Certificate[] certChain;    // signer's cert chain (when composing)
 117     PrivateKey privateKey;          // private key
 118     KeyStore store;                 // the keystore specified by -keystore
 119                                     // or the default keystore, never null
 120 
 121     String keystore; // key store file


 158     // Informational warnings
 159     private boolean hasExpiringCert = false;
 160     private boolean noTimestamp = false;
 161     private Date expireDate = new Date(0L);     // used in noTimestamp warning
 162 
 163     // Severe warnings
 164     private int weakAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg
 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     private boolean signerSelfSigned = false;
 175 
 176     private Throwable chainNotValidatedReason = null;
 177 
 178     private boolean seeWeak = false;
 179 
 180     CertificateFactory certificateFactory;
 181     CertPathValidator validator;
 182     PKIXParameters pkixParameters;
 183 
 184     public void run(String args[]) {
 185         try {
 186             args = parseArgs(args);
 187 
 188             // Try to load and install the specified providers
 189             if (providers != null) {
 190                 for (String provName: providers) {
 191                     try {
 192                         KeyStoreUtil.loadProviderByName(provName,
 193                                 providerArgs.get(provName));
 194                         if (debug) {
 195                             System.out.println("loadProviderByName: " + provName);
 196                         }
 197                     } catch (IllegalArgumentException e) {
 198                         throw new Exception(String.format(rb.getString(
 199                                 "provider.name.not.found"), provName));


 625         System.out.println(rb.getString
 626                 (".providerClass.option"));
 627         System.out.println(rb.getString
 628                 (".providerArg.option.2"));
 629         System.out.println();
 630         System.out.println(rb.getString
 631                 (".strict.treat.warnings.as.errors"));
 632         System.out.println();
 633         System.out.println(rb.getString
 634                 (".conf.url.specify.a.pre.configured.options.file"));
 635         System.out.println();
 636 
 637         System.exit(0);
 638     }
 639 
 640     void verifyJar(String jarName)
 641         throws Exception
 642     {
 643         boolean anySigned = false;  // if there exists entry inside jar signed
 644         JarFile jf = null;
 645         Map<String,String> digestMap = new HashMap<>();
 646         Map<String,PKCS7> sigMap = new HashMap<>();
 647         Map<String,String> sigNameMap = new HashMap<>();
 648         Map<String,String> unparsableSignatures = new HashMap<>();
 649 
 650         try {
 651             jf = new JarFile(jarName, true);
 652             Vector<JarEntry> entriesVec = new Vector<>();
 653             byte[] buffer = new byte[8192];
 654 
 655             Enumeration<JarEntry> entries = jf.entries();
 656             while (entries.hasMoreElements()) {
 657                 JarEntry je = entries.nextElement();
 658                 entriesVec.addElement(je);
 659                 try (InputStream is = jf.getInputStream(je)) {
 660                     String name = je.getName();
 661                     if (signatureRelated(name)
 662                             && SignatureFileVerifier.isBlockOrSF(name)) {
 663                         String alias = name.substring(name.lastIndexOf('/') + 1,
 664                                 name.lastIndexOf('.'));
 665                         try {
 666                             if (name.endsWith(".SF")) {
 667                                 Manifest sf = new Manifest(is);
 668                                 boolean found = false;
 669                                 for (Object obj : sf.getMainAttributes().keySet()) {
 670                                     String key = obj.toString();
 671                                     if (key.endsWith("-Digest-Manifest")) {
 672                                         digestMap.put(alias,
 673                                                 key.substring(0, key.length() - 16));
 674                                         found = true;
 675                                         break;
 676                                     }
 677                                 }
 678                                 if (!found) {
 679                                     unparsableSignatures.putIfAbsent(alias,
 680                                         String.format(
 681                                             rb.getString("history.unparsable"),
 682                                             name));
 683                                 }
 684                             } else {
 685                                 sigNameMap.put(alias, name);
 686                                 sigMap.put(alias, new PKCS7(is));
 687                             }
 688                         } catch (IOException ioe) {
 689                             unparsableSignatures.putIfAbsent(alias, String.format(
 690                                     rb.getString("history.unparsable"), name));
 691                         }
 692                     } else {
 693                         while (is.read(buffer, 0, buffer.length) != -1) {
 694                             // we just read. this will throw a SecurityException
 695                             // if  a signature/digest check fails.
 696                         }



 697                     }
 698                 }
 699             }
 700 
 701             Manifest man = jf.getManifest();
 702             boolean hasSignature = false;
 703 
 704             // The map to record display info, only used when -verbose provided
 705             //      key: signer info string
 706             //      value: the list of files with common key
 707             Map<String,List<String>> output = new LinkedHashMap<>();
 708 
 709             if (man != null) {
 710                 if (verbose != null) System.out.println();
 711                 Enumeration<JarEntry> e = entriesVec.elements();
 712 
 713                 String tab = rb.getString("6SPACE");
 714 
 715                 while (e.hasMoreElements()) {
 716                     JarEntry je = e.nextElement();


 834                                         String.format(rb.getString(
 835                                         ".and.d.more."), files.size()-1));
 836                             } else {
 837                                 System.out.println(files.get(0));
 838                             }
 839                         }
 840                         System.out.printf(key.substring(pipe+1));
 841                     }
 842                 }
 843                 System.out.println();
 844                 System.out.println(rb.getString(
 845                     ".s.signature.was.verified."));
 846                 System.out.println(rb.getString(
 847                     ".m.entry.is.listed.in.manifest"));
 848                 System.out.println(rb.getString(
 849                     ".k.at.least.one.certificate.was.found.in.keystore"));
 850                 if (ckaliases.size() > 0) {
 851                     System.out.println(rb.getString(
 852                         ".X.not.signed.by.specified.alias.es."));
 853                 }

 854             }
 855             if (man == null) {
 856                 System.out.println();
 857                 System.out.println(rb.getString("no.manifest."));
 858             }
 859 
 860             // If signer is a trusted cert or private entry in user's own
 861             // keystore, it can be self-signed.
 862             if (!aliasNotInStore) {
 863                 signerSelfSigned = false;
 864             }
 865 
 866             // Even if the verbose option is not specified, all out strings
 867             // must be generated so seeWeak can be updated.
 868             if (!digestMap.isEmpty()
 869                     || !sigMap.isEmpty()
 870                     || !unparsableSignatures.isEmpty()) {
 871                 if (verbose != null) {
 872                     System.out.println();
 873                 }
 874                 for (String s : sigMap.keySet()) {
 875                     if (!digestMap.containsKey(s)) {
 876                         unparsableSignatures.putIfAbsent(s, String.format(
 877                                 rb.getString("history.nosf"), s));
 878                     }
 879                 }
 880                 for (String s : digestMap.keySet()) {
 881                     PKCS7 p7 = sigMap.get(s);
 882                     if (p7 != null) {
 883                         String history;
 884                         try {
 885                             SignerInfo si = p7.getSignerInfos()[0];
 886                             X509Certificate signer = si.getCertificate(p7);
 887                             String digestAlg = digestMap.get(s);
 888                             String sigAlg = AlgorithmId.makeSigAlg(
 889                                     si.getDigestAlgorithmId().getName(),
 890                                     si.getDigestEncryptionAlgorithmId().getName());
 891                             PublicKey key = signer.getPublicKey();
 892                             PKCS7 tsToken = si.getTsToken();
 893                             if (tsToken != null) {
 894                                 SignerInfo tsSi = tsToken.getSignerInfos()[0];
 895                                 X509Certificate tsSigner = tsSi.getCertificate(tsToken);
 896                                 byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
 897                                 TimestampToken tsTokenInfo = new TimestampToken(encTsTokenInfo);
 898                                 PublicKey tsKey = tsSigner.getPublicKey();
 899                                 String tsDigestAlg = tsTokenInfo.getHashAlgorithm().getName();
 900                                 String tsSigAlg = AlgorithmId.makeSigAlg(
 901                                         tsSi.getDigestAlgorithmId().getName(),
 902                                         tsSi.getDigestEncryptionAlgorithmId().getName());
 903                                 Calendar c = Calendar.getInstance(
 904                                         TimeZone.getTimeZone("UTC"),
 905                                         Locale.getDefault(Locale.Category.FORMAT));
 906                                 c.setTime(tsTokenInfo.getDate());
 907                                 history = String.format(
 908                                         rb.getString("history.with.ts"),
 909                                         signer.getSubjectX500Principal(),
 910                                         withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
 911                                         withWeak(sigAlg, SIG_PRIMITIVE_SET),
 912                                         withWeak(key),
 913                                         c,
 914                                         tsSigner.getSubjectX500Principal(),
 915                                         withWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET),
 916                                         withWeak(tsSigAlg, SIG_PRIMITIVE_SET),
 917                                         withWeak(tsKey));
 918                             } else {
 919                                 history = String.format(
 920                                         rb.getString("history.without.ts"),
 921                                         signer.getSubjectX500Principal(),
 922                                         withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
 923                                         withWeak(sigAlg, SIG_PRIMITIVE_SET),
 924                                         withWeak(key));
 925                             }
 926                         } catch (Exception e) {
 927                             // The only usage of sigNameMap, remember the name
 928                             // of the block file if it's invalid.
 929                             history = String.format(
 930                                     rb.getString("history.unparsable"),
 931                                     sigNameMap.get(s));
 932                         }
 933                         if (verbose != null) {
 934                             System.out.println(history);
 935                         }
 936                     } else {
 937                         unparsableSignatures.putIfAbsent(s, String.format(
 938                                 rb.getString("history.nobk"), s));
 939                     }
 940                 }
 941                 if (verbose != null) {
 942                     for (String s : unparsableSignatures.keySet()) {
 943                         System.out.println(unparsableSignatures.get(s));
 944                     }
 945                 }
 946             }
 947             System.out.println();
 948             if (!anySigned) {
 949                 if (seeWeak) {
 950                     if (verbose != null) {
 951                         System.out.println(rb.getString("jar.treated.unsigned.see.weak.verbose"));
 952                         System.out.println("\n  " +
 953                                 DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS +
 954                                 "=" + Security.getProperty(DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS));
 955                     } else {
 956                         System.out.println(rb.getString("jar.treated.unsigned.see.weak"));
 957                     }
 958                 } else if (hasSignature) {
 959                     System.out.println(rb.getString("jar.treated.unsigned"));
 960                 } else {
 961                     System.out.println(rb.getString("jar.is.unsigned"));
 962                 }
 963             } else {
 964                 boolean warningAppeared = false;
 965                 boolean errorAppeared = false;
 966                 if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
 967                         notYetValidCert || chainNotValidated || hasExpiredCert ||
 968                         hasUnsignedEntry || signerSelfSigned || (weakAlg != 0) ||
 969                         aliasNotInStore || notSignedByAlias) {
 970 
 971                     if (strict) {
 972                         System.out.println(rb.getString("jar.verified.with.signer.errors."));
 973                         System.out.println();
 974                         System.out.println(rb.getString("Error."));
 975                         errorAppeared = true;
 976                     } else {
 977                         System.out.println(rb.getString("jar.verified."));
 978                         System.out.println();
 979                         System.out.println(rb.getString("Warning."));
 980                         warningAppeared = true;
 981                     }
 982 
 983                     if (weakAlg != 0) {
 984                         // In fact, jarsigner verification did not catch this
 985                         // since it has not read the JarFile content itself.
 986                         // Everything is done with JarFile API. The signing
 987                         // history (digestMap etc) will show these info and
 988                         // print out proper warnings.
 989                     }
 990 
 991                     if (badKeyUsage) {
 992                         System.out.println(
 993                             rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
 994                     }
 995 
 996                     if (badExtendedKeyUsage) {
 997                         System.out.println(
 998                             rb.getString("This.jar.contains.entries.whose.signer.certificate.s.ExtendedKeyUsage.extension.doesn.t.allow.code.signing."));
 999                     }
1000 
1001                     if (badNetscapeCertType) {
1002                         System.out.println(
1003                             rb.getString("This.jar.contains.entries.whose.signer.certificate.s.NetscapeCertType.extension.doesn.t.allow.code.signing."));
1004                     }
1005 
1006                     if (hasUnsignedEntry) {
1007                         System.out.println(rb.getString(
1008                             "This.jar.contains.unsigned.entries.which.have.not.been.integrity.checked."));


1059                         System.out.println(rb.getString(
1060                                 "Re.run.with.the.verbose.and.certs.options.for.more.details."));
1061                     }
1062                 }
1063             }
1064             return;
1065         } catch (Exception e) {
1066             System.out.println(rb.getString("jarsigner.") + e);
1067             if (debug) {
1068                 e.printStackTrace();
1069             }
1070         } finally { // close the resource
1071             if (jf != null) {
1072                 jf.close();
1073             }
1074         }
1075 
1076         System.exit(1);
1077     }
1078 
1079     private String withWeak(String alg, Set<CryptoPrimitive> primitiveSet) {
1080         if (DISABLED_CHECK.permits(primitiveSet, alg, null)) {
1081             return alg;
1082         } else {
1083             seeWeak = true;
1084             return String.format(rb.getString("with.weak"), alg);
1085         }
1086     }
1087 
1088     private String withWeak(PublicKey key) {
1089         if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
1090             return String.format(
1091                     rb.getString("key.bit"), KeyUtil.getKeySize(key));
1092         } else {
1093             seeWeak = true;
1094             return String.format(
1095                     rb.getString("key.bit.weak"), KeyUtil.getKeySize(key));
1096         }
1097     }
1098 
1099     private static MessageFormat validityTimeForm = null;
1100     private static MessageFormat notYetTimeForm = null;
1101     private static MessageFormat expiredTimeForm = null;
1102     private static MessageFormat expiringTimeForm = null;
1103 
1104     /*
1105      * Display some details about a certificate:
1106      *
1107      * [<tab>] <cert-type> [", " <subject-DN>] [" (" <keystore-entry-alias> ")"]
1108      * [<validity-period> | <expiry-warning>]
1109      *
1110      * Note: no newline character at the end
1111      */
1112     String printCert(String tab, Certificate c, boolean checkValidityPeriod,
1113         Date timestamp, boolean checkUsage) {
1114 
1115         StringBuilder certStr = new StringBuilder();
1116         String space = rb.getString("SPACE");
1117         X509Certificate x509Cert = null;
1118 


1268     int inKeyStore(CodeSigner[] signers) {
1269 
1270         if (signers == null)
1271             return 0;
1272 
1273         int output = 0;
1274 
1275         for (CodeSigner signer: signers) {
1276             int result = inKeyStoreForOneSigner(signer);
1277             output |= result;
1278         }
1279         if (ckaliases.size() > 0 && (output & SIGNED_BY_ALIAS) == 0) {
1280             output |= NOT_ALIAS;
1281         }
1282         return output;
1283     }
1284 
1285     void signJar(String jarName, String alias)
1286             throws Exception {
1287 
1288         if (digestalg != null && !DISABLED_CHECK.permits(
1289                 DIGEST_PRIMITIVE_SET, digestalg, null)) {




1290             weakAlg |= 1;
1291         }
1292         if (tSADigestAlg != null && !DISABLED_CHECK.permits(
1293                 DIGEST_PRIMITIVE_SET, tSADigestAlg, null)) {
1294             weakAlg |= 4;
1295         }
1296         if (sigalg != null && !DISABLED_CHECK.permits(
1297                 SIG_PRIMITIVE_SET , sigalg, null)) {
1298             weakAlg |= 2;
1299         }
1300         if (!DISABLED_CHECK.permits(
1301                 SIG_PRIMITIVE_SET, privateKey)) {
1302             weakAlg |= 8;
1303         }
1304 
1305         boolean aliasUsed = false;
1306         X509Certificate tsaCert = null;
1307 
1308         if (sigfile == null) {
1309             sigfile = alias;
1310             aliasUsed = true;
1311         }
1312 
1313         if (sigfile.length() > 8) {
1314             sigfile = sigfile.substring(0, 8).toUpperCase(Locale.ENGLISH);
1315         } else {
1316             sigfile = sigfile.toUpperCase(Locale.ENGLISH);
1317         }
1318 
1319         StringBuilder tmpSigFile = new StringBuilder(sigfile.length());
1320         for (int j = 0; j < sigfile.length(); j++) {
1321             char c = sigfile.charAt(j);
1322             if (!
1323                     ((c>= 'A' && c<= 'Z') ||


1528                     System.out.println(
1529                             rb.getString("The.signer.s.certificate.is.self.signed."));
1530                 }
1531 
1532                 if ((weakAlg & 1) == 1) {
1533                     System.out.println(String.format(
1534                             rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
1535                             digestalg, "-digestalg"));
1536                 }
1537 
1538                 if ((weakAlg & 2) == 2) {
1539                     System.out.println(String.format(
1540                             rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
1541                             sigalg, "-sigalg"));
1542                 }
1543                 if ((weakAlg & 4) == 4) {
1544                     System.out.println(String.format(
1545                             rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
1546                             tSADigestAlg, "-tsadigestalg"));
1547                 }
1548                 if ((weakAlg & 8) == 8) {
1549                     System.out.println(String.format(
1550                             rb.getString("The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk."),
1551                             privateKey.getAlgorithm(), KeyUtil.getKeySize(privateKey)));
1552                 }
1553             } else {
1554                 System.out.println(rb.getString("jar.signed."));
1555             }
1556             if (hasExpiringCert || noTimestamp) {
1557                 if (!warningAppeared) {
1558                     System.out.println();
1559                     System.out.println(rb.getString("Warning."));
1560                 }
1561 
1562                 if (hasExpiringCert) {
1563                     System.out.println(
1564                             rb.getString("The.signer.certificate.will.expire.within.six.months."));
1565                 }
1566 
1567                 if (noTimestamp) {
1568                     System.out.println(
1569                             String.format(rb.getString("no.timestamp.signing"), expireDate));
1570                 }
1571             }
1572 


< prev index next >