< prev index next >

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

Print this page
rev 15871 : 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     // PROPERTY_CERTPATH_DISABLED_ALGS is currently more restrictive than
  94     // PROPERTY_JAR_DISABLED_ALGS and we used it at signing time.
  95     private static final DisabledAlgorithmConstraints VERIFY_CHECK =
  96             new DisabledAlgorithmConstraints(
  97                     DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
  98     private static final DisabledAlgorithmConstraints SIGN_CHECK =
  99             new DisabledAlgorithmConstraints(
 100                     DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
 101 
 102     private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = Collections
 103             .unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
 104     private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
 105             .unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
 106 
 107     // Attention:
 108     // This is the entry that get launched by the security tool jarsigner.
 109     public static void main(String args[]) throws Exception {
 110         Main js = new Main();
 111         js.run(args);
 112     }
 113 
 114     static final String VERSION = "1.0";
 115 
 116     static final int IN_KEYSTORE = 0x01;        // signer is in keystore
 117     static final int NOT_ALIAS = 0x04;          // alias list is NOT empty and
 118                                                 // signer is not in alias list
 119     static final int SIGNED_BY_ALIAS = 0x08;    // signer is in alias list
 120 
 121     X509Certificate[] certChain;    // signer's cert chain (when composing)
 122     PrivateKey privateKey;          // private key
 123     KeyStore store;                 // the keystore specified by -keystore
 124                                     // or the default keystore, never null
 125 
 126     String keystore; // key store file


 163     // Informational warnings
 164     private boolean hasExpiringCert = false;
 165     private boolean noTimestamp = false;
 166     private Date expireDate = new Date(0L);     // used in noTimestamp warning
 167 
 168     // Severe warnings
 169     private int weakAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg
 170     private boolean hasExpiredCert = false;
 171     private boolean notYetValidCert = false;
 172     private boolean chainNotValidated = false;
 173     private boolean notSignedByAlias = false;
 174     private boolean aliasNotInStore = false;
 175     private boolean hasUnsignedEntry = false;
 176     private boolean badKeyUsage = false;
 177     private boolean badExtendedKeyUsage = false;
 178     private boolean badNetscapeCertType = false;
 179     private boolean signerSelfSigned = false;
 180 
 181     private Throwable chainNotValidatedReason = null;
 182 
 183     private boolean seeWeak = false;
 184 
 185     CertificateFactory certificateFactory;
 186     CertPathValidator validator;
 187     PKIXParameters pkixParameters;
 188 
 189     public void run(String args[]) {
 190         try {
 191             args = parseArgs(args);
 192 
 193             // Try to load and install the specified providers
 194             if (providers != null) {
 195                 for (String provName: providers) {
 196                     try {
 197                         KeyStoreUtil.loadProviderByName(provName,
 198                                 providerArgs.get(provName));
 199                         if (debug) {
 200                             System.out.println("loadProviderByName: " + provName);
 201                         }
 202                     } catch (IllegalArgumentException e) {
 203                         throw new Exception(String.format(rb.getString(
 204                                 "provider.name.not.found"), provName));


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



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


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

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


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


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




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


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


< prev index next >