diff --git a/src/share/classes/sun/security/tools/KeyStoreUtil.java b/src/share/classes/sun/security/tools/KeyStoreUtil.java index ecfba5feee2f0d76e39dd6d3a48d55e055fc1394..4fd80760b33da9f7c0f30dbd12152ccdf877dfe2 100644 --- a/src/share/classes/sun/security/tools/KeyStoreUtil.java +++ b/src/share/classes/sun/security/tools/KeyStoreUtil.java @@ -35,6 +35,7 @@ import java.net.URL; import java.security.KeyStore; +import java.security.cert.X509Certificate; import java.text.Collator; import java.util.Locale; @@ -58,6 +59,25 @@ public class KeyStoreUtil { collator.setStrength(Collator.PRIMARY); }; + /** + * Returns true if the certificate is self-signed, false otherwise. + */ + public static boolean isSelfSigned(X509Certificate cert) { + return signedBy(cert, cert); + } + + public static boolean signedBy(X509Certificate end, X509Certificate ca) { + if (!ca.getSubjectX500Principal().equals(end.getIssuerX500Principal())) { + return false; + } + try { + end.verify(ca.getPublicKey()); + return true; + } catch (Exception e) { + return false; + } + } + /** * Returns true if KeyStore has a password. This is true except for * MSCAPI KeyStores diff --git a/src/share/classes/sun/security/tools/jarsigner/Main.java b/src/share/classes/sun/security/tools/jarsigner/Main.java index 0d22d7d82fd93cb21347cec890c1edbc34a5e521..63496b1607e0b83d7219bcfcae7aa17fcb6d8fbb 100644 --- a/src/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/share/classes/sun/security/tools/jarsigner/Main.java @@ -174,6 +174,7 @@ public class Main { private Date expireDate = new Date(0L); // used in noTimestamp warning // Severe warnings + private int weakAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg private boolean hasExpiredCert = false; private boolean notYetValidCert = false; private boolean chainNotValidated = false; @@ -183,6 +184,9 @@ public class Main { private boolean badKeyUsage = false; private boolean badExtendedKeyUsage = false; private boolean badNetscapeCertType = false; + private boolean signerSelfSigned = false; + + private Throwable chainNotValidatedReason = null; private boolean seeWeak = false; @@ -275,7 +279,7 @@ public class Main { if (strict) { int exitCode = 0; - if (chainNotValidated || hasExpiredCert || notYetValidCert) { + if (weakAlg != 0 || chainNotValidated || hasExpiredCert || notYetValidCert || signerSelfSigned) { exitCode |= 4; } if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType) { @@ -890,6 +894,12 @@ public class Main { } System.out.println(); + // If signer is a trusted cert or private entry in user's own + // keystore, it can be self-signed. + if (!aliasNotInStore) { + signerSelfSigned = false; + } + if (!anySigned) { if (seeWeak) { if (verbose != null) { @@ -910,7 +920,7 @@ public class Main { boolean errorAppeared = false; if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType || notYetValidCert || chainNotValidated || hasExpiredCert || - hasUnsignedEntry || + hasUnsignedEntry || signerSelfSigned || (weakAlg != 0) || aliasNotInStore || notSignedByAlias) { if (strict) { @@ -925,6 +935,12 @@ public class Main { warningAppeared = true; } + if (weakAlg != 0) { + // In fact, jarsigner verification did not catch this + // since it has not read the JarFile content itself. + // Everything is done with JarFile API. + } + if (badKeyUsage) { System.out.println( rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing.")); @@ -954,8 +970,9 @@ public class Main { } if (chainNotValidated) { - System.out.println( - rb.getString("This.jar.contains.entries.whose.certificate.chain.is.not.validated.")); + System.out.println(String.format( + rb.getString("This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1"), + chainNotValidatedReason.getLocalizedMessage())); } if (notSignedByAlias) { @@ -966,6 +983,11 @@ public class Main { if (aliasNotInStore) { System.out.println(rb.getString("This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore.")); } + + if (signerSelfSigned) { + System.out.println(rb.getString( + "This.jar.contains.entries.whose.signer.certificate.is.self.signed.")); + } } else { System.out.println(rb.getString("jar.verified.")); } @@ -1218,7 +1240,25 @@ public class Main { } void signJar(String jarName, String alias, String[] args) - throws Exception { + throws Exception { + + DisabledAlgorithmConstraints dac = + new DisabledAlgorithmConstraints( + DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); + + if (digestalg != null && !dac.permits( + Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), digestalg, null)) { + weakAlg |= 1; + } + if (tSADigestAlg != null && !dac.permits( + Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), tSADigestAlg, null)) { + weakAlg |= 4; + } + if (sigalg != null && !dac.permits( + Collections.singleton(CryptoPrimitive.SIGNATURE), sigalg, null)) { + weakAlg |= 2; + } + boolean aliasUsed = false; X509Certificate tsaCert = null; @@ -1586,8 +1626,8 @@ public class Main { } boolean warningAppeared = false; - if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType || - notYetValidCert || chainNotValidated || hasExpiredCert) { + if (weakAlg != 0 || badKeyUsage || badExtendedKeyUsage || badNetscapeCertType || + notYetValidCert || chainNotValidated || hasExpiredCert || signerSelfSigned) { if (strict) { System.out.println(rb.getString("jar.signed.with.signer.errors.")); System.out.println(); @@ -1623,8 +1663,31 @@ public class Main { } if (chainNotValidated) { + System.out.println(String.format( + rb.getString("The.signer.s.certificate.chain.is.not.validated.reason.1"), + chainNotValidatedReason.getLocalizedMessage())); + } + + if (signerSelfSigned) { System.out.println( - rb.getString("The.signer.s.certificate.chain.is.not.validated.")); + rb.getString("The.signer.s.certificate.is.self.signed.")); + } + + if ((weakAlg & 1) == 1) { + System.out.println(String.format( + rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."), + digestalg, "-digestalg")); + } + + if ((weakAlg & 2) == 2) { + System.out.println(String.format( + rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."), + sigalg, "-sigalg")); + } + if ((weakAlg & 4) == 4) { + System.out.println(String.format( + rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."), + tSADigestAlg, "-tsadigestalg")); } } else { System.out.println(rb.getString("jar.signed.")); @@ -1737,10 +1800,15 @@ public class Main { // No more warning, we alreay have hasExpiredCert or notYetValidCert } else { chainNotValidated = true; + chainNotValidatedReason = e; s.append(tab + rb.getString(".CertPath.not.validated.") + e.getLocalizedMessage() + "]\n"); // TODO } } + if (certs.size() == 1 + && KeyStoreUtil.isSelfSigned((X509Certificate)certs.get(0))) { + signerSelfSigned = true; + } String result = s.toString(); cacheForSignerInfo.put(signer, result); return result; @@ -2044,12 +2112,17 @@ public class Main { if (e.getCause() != null && (e.getCause() instanceof CertificateExpiredException || e.getCause() instanceof CertificateNotYetValidException)) { - // No more warning, we alreay have hasExpiredCert or notYetValidCert + // No more warning, we already have hasExpiredCert or notYetValidCert } else { chainNotValidated = true; + chainNotValidatedReason = e; } } + if (KeyStoreUtil.isSelfSigned(certChain[0])) { + signerSelfSigned = true; + } + try { if (!token && keypass == null) key = store.getKey(alias, storepass); diff --git a/src/share/classes/sun/security/tools/jarsigner/Resources.java b/src/share/classes/sun/security/tools/jarsigner/Resources.java index bff9dd718d5f68b71ccd930f6e209066a0af0597..21f842fc9cdce8139d486163dae21c544732ed42 100644 --- a/src/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/src/share/classes/sun/security/tools/jarsigner/Resources.java @@ -224,6 +224,8 @@ public class Resources extends java.util.ListResourceBundle { "This jar contains entries whose signer certificate will expire within six months. "}, {"This.jar.contains.entries.whose.signer.certificate.is.not.yet.valid.", "This jar contains entries whose signer certificate is not yet valid. "}, + {"This.jar.contains.entries.whose.signer.certificate.is.self.signed.", + "This jar contains entries whose signer certificate is self-signed."}, {"Re.run.with.the.verbose.option.for.more.details.", "Re-run with the -verbose option for more details."}, {"Re.run.with.the.verbose.and.certs.options.for.more.details.", @@ -248,10 +250,14 @@ public class Resources extends java.util.ListResourceBundle { "This jar contains entries whose signer certificate's NetscapeCertType extension doesn't allow code signing."}, {".{0}.extension.does.not.support.code.signing.", "[{0} extension does not support code signing]"}, - {"The.signer.s.certificate.chain.is.not.validated.", - "The signer's certificate chain is not validated."}, - {"This.jar.contains.entries.whose.certificate.chain.is.not.validated.", - "This jar contains entries whose certificate chain is not validated."}, + {"The.signer.s.certificate.chain.is.not.validated.reason.1", + "The signer's certificate chain is not validated. Reason: %s"}, + {"The.signer.s.certificate.is.self.signed.", + "The signer's certificate is self-signed."}, + {"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.", + "The %1$s algorithm specified for the %2$s option is considered a security risk."}, + {"This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1", + "This jar contains entries whose certificate chain is not validated. Reason: %s"}, {"no.timestamp.signing", "No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."}, {"no.timestamp.verifying", diff --git a/src/share/classes/sun/security/tools/keytool/Main.java b/src/share/classes/sun/security/tools/keytool/Main.java index fac7b5dccd746ab46f60d56ca765321aef8f4e43..2a3a8e632d952e200227ff26f44f18d26b1dde49 100644 --- a/src/share/classes/sun/security/tools/keytool/Main.java +++ b/src/share/classes/sun/security/tools/keytool/Main.java @@ -1359,7 +1359,7 @@ public final class Main { for (Certificate ca: keyStore.getCertificateChain(alias)) { if (ca instanceof X509Certificate) { X509Certificate xca = (X509Certificate)ca; - if (!isSelfSigned(xca)) { + if (!KeyStoreUtil.isSelfSigned(xca)) { dumpCert(xca, out); } } @@ -2861,7 +2861,7 @@ public final class Main { // if certificate is self-signed, make sure it verifies boolean selfSigned = false; - if (isSelfSigned(cert)) { + if (KeyStoreUtil.isSelfSigned(cert)) { cert.verify(cert.getPublicKey()); selfSigned = true; } @@ -3164,25 +3164,6 @@ public final class Main { } } - /** - * Returns true if the certificate is self-signed, false otherwise. - */ - private boolean isSelfSigned(X509Certificate cert) { - return signedBy(cert, cert); - } - - private boolean signedBy(X509Certificate end, X509Certificate ca) { - if (!ca.getSubjectDN().equals(end.getIssuerDN())) { - return false; - } - try { - end.verify(ca.getPublicKey()); - return true; - } catch (Exception e) { - return false; - } - } - /** * Locates a signer for a given certificate from a given keystore and * returns the signer's certificate. @@ -3523,7 +3504,7 @@ public final class Main { // find a cert in the reply who signs thisCert int j; for (j=i; j certToVerify, Vector> chain, Hashtable>> certs) { - if (isSelfSigned(certToVerify.snd)) { + if (KeyStoreUtil.isSelfSigned(certToVerify.snd)) { // reached self-signed root cert; // no verification needed because it's trusted. chain.addElement(certToVerify); diff --git a/test/sun/security/tools/jarsigner/TsacertOptionTest.java b/test/sun/security/tools/jarsigner/TsacertOptionTest.java index 811ffd9c221fdf2877c857f17d1b77df30ee30ea..96116e1efde853f0759117812ae5ddc83b065b98 100644 --- a/test/sun/security/tools/jarsigner/TsacertOptionTest.java +++ b/test/sun/security/tools/jarsigner/TsacertOptionTest.java @@ -46,6 +46,7 @@ public class TsacertOptionTest { + ".txt"; private static final String PASSWORD = "changeit"; private static final String KEYSTORE = "ks.jks"; + private static final String CA_KEY_ALIAS = "ca"; private static final String SIGNING_KEY_ALIAS = "sign_alias"; private static final String TSA_KEY_ALIAS = "ts"; private static final String KEY_ALG = "RSA"; @@ -73,20 +74,52 @@ public class TsacertOptionTest { // look for free network port for TSA service int port = jdk.testlibrary.Utils.getFreePort(); - String host = jdk.testlibrary.Utils.getHostname(); + String host = "127.0.0.1"; String tsaUrl = "http://" + host + ":" + port; // create key pair for jar signing ProcessTools.executeCommand(KEYTOOL, "-genkey", - "-alias", SIGNING_KEY_ALIAS, + "-alias", CA_KEY_ALIAS, "-keyalg", KEY_ALG, "-keysize", Integer.toString(KEY_SIZE), "-keystore", KEYSTORE, "-storepass", PASSWORD, "-keypass", PASSWORD, - "-dname", "CN=Test", + "-dname", "CN=CA", "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", SIGNING_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test").shouldHaveExitValue(0); + ProcessTools.executeCommand(KEYTOOL, + "-certreq", + "-alias", SIGNING_KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-file", "certreq").shouldHaveExitValue(0); + ProcessTools.executeCommand(KEYTOOL, + "-gencert", + "-alias", CA_KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-validity", Integer.toString(VALIDITY), + "-infile", "certreq", + "-outfile", "cert").shouldHaveExitValue(0); + ProcessTools.executeCommand(KEYTOOL, + "-importcert", + "-alias", SIGNING_KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-file", "cert").shouldHaveExitValue(0); // create key pair for TSA service // SubjectInfoAccess extension contains URL to TSA service diff --git a/test/sun/security/tools/jarsigner/Warning.java b/test/sun/security/tools/jarsigner/Warning.java new file mode 100644 index 0000000000000000000000000000000000000000..e5c58edcb846d759e08a5f45e07fee20cf319aeb --- /dev/null +++ b/test/sun/security/tools/jarsigner/Warning.java @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.testlibrary.JDKToolLauncher; +import jdk.testlibrary.JarUtils; +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; + +/** + * @test + * @bug 8024302 8026037 8130132 + * @summary warnings, errors and -strict + * @library /lib/testlibrary + */ +public class Warning { + + public static void main(String[] args) throws Throwable { + + Files.deleteIfExists(Paths.get("ks")); + + newCert("ca", "-validity 365000"); + + recreateJar(); + + newCert("a"); + run("jarsigner", "a.jar a") + .shouldContain("is self-signed"); + run("jarsigner", "a.jar a -strict") + .shouldContain("is self-signed") + .shouldHaveExitValue(4); + // Trusted entry can be self-signed without a warning + run("jarsigner", "-verify a.jar") + .shouldNotContain("is self-signed") + .shouldNotContain("not signed by alias in this keystore"); + run("keytool", "-delete -alias a"); + // otherwise a warning will be shown + run("jarsigner", "-verify a.jar") + .shouldContain("is self-signed") + .shouldContain("not signed by alias in this keystore"); + + recreateJar(); + + newCert("b"); + issueCert("b"); + run("jarsigner", "a.jar b") + .shouldNotContain("is self-signed"); + run("jarsigner", "-verify a.jar") + .shouldNotContain("is self-signed"); + + run("jarsigner", "a.jar b -digestalg MD5") + .shouldContain("-digestalg option is considered a security risk."); + run("jarsigner", "a.jar b -digestalg MD5 -strict") + .shouldHaveExitValue(4) + .shouldContain("-digestalg option is considered a security risk."); + run("jarsigner", "a.jar b -sigalg MD5withRSA") + .shouldContain("-sigalg option is considered a security risk"); + + issueCert("b", "-sigalg MD5withRSA"); + run("jarsigner", "a.jar b") + .shouldMatch("chain is not validated. Reason:.*MD5withRSA"); + + recreateJar(); + + newCert("c", "-keysize 512"); + issueCert("c"); + run("jarsigner", "a.jar c") + .shouldContain("chain is not validated. " + + "Reason: Algorithm constraints check failed"); + + recreateJar(); + + newCert("s1"); issueCert("s1", "-startdate 2000/01/01 -validity 36525"); + run("jarsigner", "a.jar s1") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("Error:") + .shouldContain("timestamp").shouldContain("2100-01-01") + .shouldNotContain("with signer errors"); + run("jarsigner", "a.jar s1 -strict") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("Error:") + .shouldContain("timestamp").shouldContain("2100-01-01") + .shouldNotContain("with signer errors"); + run("jarsigner", "a.jar s1 -verify") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("Error:") + .shouldContain("timestamp").shouldContain("2100-01-01") + .shouldNotContain("with signer errors"); + run("jarsigner", "a.jar s1 -verify -strict") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("Error:") + .shouldContain("timestamp").shouldContain("2100-01-01") + .shouldNotContain("with signer errors"); + + recreateJar(); + + newCert("s2"); issueCert("s2", "-validity 100"); + run("jarsigner", "a.jar s2") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("Error:") + .shouldContain("timestamp") + .shouldContain("will expire") + .shouldNotContain("with signer errors"); + run("jarsigner", "a.jar s2 -strict") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("Error:") + .shouldContain("timestamp") + .shouldContain("will expire") + .shouldNotContain("with signer errors"); + run("jarsigner", "a.jar s2 -verify") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("Error:") + .shouldContain("timestamp") + .shouldContain("will expire") + .shouldNotContain("with signer errors"); + run("jarsigner", "a.jar s2 -verify -strict") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("Error:") + .shouldContain("timestamp") + .shouldContain("will expire") + .shouldNotContain("with signer errors"); + + recreateJar(); + + newCert("s3"); issueCert("s3", "-startdate -200d -validity 100"); + run("jarsigner", "a.jar s3") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldContain("has expired") + .shouldNotContain("with signer errors") + .shouldNotContain("Error:"); + run("jarsigner", "a.jar s3 -strict") + .shouldHaveExitValue(4) + .shouldContain("with signer errors") + .shouldMatch("(?s).*Error:.*has expired.*Warning:.*"); + run("jarsigner", "a.jar s3 -verify") + .shouldHaveExitValue(0) + .shouldContain("Warning:") + .shouldNotContain("with signer errors") + .shouldNotContain("Error:"); + run("jarsigner", "a.jar s3 -verify -strict") + .shouldHaveExitValue(4) + .shouldContain("with signer errors") + .shouldMatch("(?s).*Error:.*has expired.*Warning:.*"); + } + + // Creates a new jar without signature + static void recreateJar() throws Exception { + JarUtils.createJar("a.jar", "ks"); + } + + // Creates a self-signed cert for alias with zero or more -genkey options + static void newCert(String alias, String... more) throws Throwable { + String args = "-genkeypair -alias " + alias + " -dname CN=" + alias; + for (String s: more) { + args += " " + s; + } + run("keytool", args).shouldHaveExitValue(0); + } + + // Asks ca to issue a cert to alias with zero or more -gencert options + static void issueCert(String alias, String...more) throws Throwable { + String req = run("keytool", "-certreq -alias " + alias) + .shouldHaveExitValue(0).getStdout(); + String args = "-gencert -alias ca -rfc"; + for (String s: more) { + args += " " + s; + } + String cert = run("keytool", args, req) + .shouldHaveExitValue(0).getStdout(); + run("keytool", "-import -alias " + alias, cert).shouldHaveExitValue(0); + } + + // Runs a java tool with command line arguments + static OutputAnalyzer run(String command, String args) + throws Throwable { + return run(command, args, null); + } + + // Runs a java tool with command line arguments and an optional input block + static OutputAnalyzer run(String command, String args, String input) + throws Throwable { + JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(command); + launcher.addVMArg("-Duser.language=en").addVMArg("-Duser.country=US"); + switch (command) { + case "keytool": + for (String s: new String[] { + "-keystore", "ks", "-storepass", "changeit", + "-storetype", "jks", + "-keypass", "changeit", "-keyalg", "rsa", "-debug"}) { + launcher.addToolArg(s); + } + break; + case "jarsigner": + for (String s: new String[] { + "-keystore", "ks", "-storepass", "changeit", + "-storetype", "jks"}) { + launcher.addToolArg(s); + } + break; + } + for (String arg: args.split(" ")) { + launcher.addToolArg(arg); + } + String[] cmd = launcher.getCommand(); + ProcessBuilder pb = new ProcessBuilder(cmd); + OutputAnalyzer out = ProcessTools.executeProcess(pb, input); + System.out.println("======================"); + System.out.println(Arrays.toString(cmd)); + String msg = " stdout: [" + out.getStdout() + "];\n" + + " stderr: [" + out.getStderr() + "]\n" + + " exitValue = " + out.getExitValue() + "\n"; + System.out.println(msg); + return out; + } +} + diff --git a/test/sun/security/tools/jarsigner/concise_jarsigner.sh b/test/sun/security/tools/jarsigner/concise_jarsigner.sh index 34e7b3240c624c79b2a4a086e8cbe995a17a7b29..8033b8b287a36850af6b791d2487cf280c84983b 100644 --- a/test/sun/security/tools/jarsigner/concise_jarsigner.sh +++ b/test/sun/security/tools/jarsigner/concise_jarsigner.sh @@ -139,19 +139,19 @@ LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "more)" | wc -l` # 16 and 32 already covered in the first part # ========================================================== -$KT -genkeypair -alias expired -dname CN=expired -startdate -10m -$KT -genkeypair -alias notyetvalid -dname CN=notyetvalid -startdate +1m -$KT -genkeypair -alias badku -dname CN=badku -ext KU=cRLSign -validity 365 -$KT -genkeypair -alias badeku -dname CN=badeku -ext EKU=sa -validity 365 -$KT -genkeypair -alias goodku -dname CN=goodku -ext KU=dig -validity 365 -$KT -genkeypair -alias goodeku -dname CN=goodeku -ext EKU=codesign -validity 365 - -# badchain signed by ca, but ca is removed later -$KT -genkeypair -alias badchain -dname CN=badchain -validity 365 $KT -genkeypair -alias ca -dname CN=ca -ext bc -validity 365 -$KT -certreq -alias badchain | $KT -gencert -alias ca -validity 365 | \ - $KT -importcert -alias badchain -$KT -delete -alias ca +$KT -genkeypair -alias expired -dname CN=expired +$KT -certreq -alias expired | $KT -gencert -alias ca -startdate -10m | $KT -import -alias expired +$KT -genkeypair -alias notyetvalid -dname CN=notyetvalid +$KT -certreq -alias notyetvalid | $KT -gencert -alias ca -startdate +1m | $KT -import -alias notyetvalid +$KT -genkeypair -alias badku -dname CN=badku +$KT -certreq -alias badku | $KT -gencert -alias ca -ext KU=cRLSign -validity 365 | $KT -import -alias badku +$KT -genkeypair -alias badeku -dname CN=badeku +$KT -certreq -alias badeku | $KT -gencert -alias ca -ext EKU=sa -validity 365 | $KT -import -alias badeku +$KT -genkeypair -alias goodku -dname CN=goodku +$KT -certreq -alias goodku | $KT -gencert -alias ca -ext KU=dig -validity 365 | $KT -import -alias goodku +$KT -genkeypair -alias goodeku -dname CN=goodeku +$KT -certreq -alias goodeku | $KT -gencert -alias ca -ext EKU=codesign -validity 365 | $KT -import -alias goodeku $JARSIGNER -strict -keystore js.jks -storepass changeit a.jar expired [ $? = 4 ] || exit $LINENO @@ -171,6 +171,12 @@ $JARSIGNER -strict -keystore js.jks -storepass changeit a.jar goodku $JARSIGNER -strict -keystore js.jks -storepass changeit a.jar goodeku [ $? = 0 ] || exit $LINENO +# badchain signed by ca, but ca is removed later +$KT -genkeypair -alias badchain -dname CN=badchain -validity 365 +$KT -certreq -alias badchain | $KT -gencert -alias ca -validity 365 | \ + $KT -importcert -alias badchain +$KT -delete -alias ca + $JARSIGNER -strict -keystore js.jks -storepass changeit a.jar badchain [ $? = 4 ] || exit $LINENO @@ -181,18 +187,22 @@ $JARSIGNER -verify a.jar # Third part: -certchain test # ========================================================== -# altchain signed by ca2, but ca2 is removed later +# altchain signed by ca2 $KT -genkeypair -alias altchain -dname CN=altchain -validity 365 $KT -genkeypair -alias ca2 -dname CN=ca2 -ext bc -validity 365 $KT -certreq -alias altchain | $KT -gencert -alias ca2 -validity 365 -rfc > certchain $KT -exportcert -alias ca2 -rfc >> certchain -$KT -delete -alias ca2 -# Now altchain is still self-signed +# Self-signed cert does not work $JARSIGNER -strict -keystore js.jks -storepass changeit a.jar altchain +[ $? = 4 ] || exit $LINENO + +# -certchain works +$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain [ $? = 0 ] || exit $LINENO -# If -certchain is used, then it's bad +# but if ca2 is removed, -certchain does not work +$KT -delete -alias ca2 $JARSIGNER -strict -keystore js.jks -storepass changeit -certchain certchain a.jar altchain [ $? = 4 ] || exit $LINENO diff --git a/test/sun/security/tools/jarsigner/ec.sh b/test/sun/security/tools/jarsigner/ec.sh index fc66bbc8f9e2daba5f189c53db0947b38531bfbe..442e854635e67bd038b18f6d22b53a467030eb95 100644 --- a/test/sun/security/tools/jarsigner/ec.sh +++ b/test/sun/security/tools/jarsigner/ec.sh @@ -53,11 +53,20 @@ rm $KS $JFILE echo A > A $JAR cvf $JFILE A -$KT -alias a -dname CN=a -keyalg ec -genkey -validity 300 || exit 11 -$KT -alias b -dname CN=b -keyalg ec -genkey -validity 300 || exit 12 +$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 || exit 11 + +$KT -alias a -dname CN=a -keyalg ec -genkey || exit 11 +$KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 111 + +$KT -alias b -dname CN=b -keyalg ec -genkey || exit 12 +$KT -alias b -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias b || exit 121 + # Ensure that key length is sufficient for the intended hash (SHA512withECDSA) -$KT -alias c -dname CN=c -keyalg ec -genkey -validity 300 -keysize 521 || exit 13 +$KT -alias c -dname CN=c -keyalg ec -genkey -keysize 521 || exit 13 +$KT -alias c -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias c || exit 131 + $KT -alias x -dname CN=x -keyalg ec -genkey -validity 300 || exit 14 +$KT -alias x -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias x || exit 141 $JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 21 $JARSIGNER -keystore $KS -storepass changeit $JFILE b -debug -strict -sigalg SHA1withECDSA || exit 22 diff --git a/test/sun/security/tools/jarsigner/onlymanifest.sh b/test/sun/security/tools/jarsigner/onlymanifest.sh index 37551a86fac3787c98527a95a02ce83433e29ff7..bbc90a1b3a889a067aedbbecdc6c09a6579db418 100644 --- a/test/sun/security/tools/jarsigner/onlymanifest.sh +++ b/test/sun/security/tools/jarsigner/onlymanifest.sh @@ -57,12 +57,14 @@ rm $KS $JFILE 2> /dev/null echo "Key: Value" > manifest $JAR cvfm $JFILE manifest -$KT -alias a -dname CN=a -genkey -validity 300 || exit 1 -$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 2 +$KT -alias ca -dname CN=ca -genkey -validity 300 || exit 1 +$KT -alias a -dname CN=a -genkey -validity 300 || exit 2 +$KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 3 +$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 4 $JARSIGNER -keystore $KS -storepass changeit -verify $JFILE a -debug -strict \ - > onlymanifest.out || exit 3 + > onlymanifest.out || exit 5 -grep unsigned onlymanifest.out && exit 4 +grep unsigned onlymanifest.out && exit 6 exit 0 diff --git a/test/sun/security/tools/jarsigner/warnings.sh b/test/sun/security/tools/jarsigner/warnings.sh deleted file mode 100644 index fbe745585ae33e08a30723c091945b91bb4021f1..0000000000000000000000000000000000000000 --- a/test/sun/security/tools/jarsigner/warnings.sh +++ /dev/null @@ -1,119 +0,0 @@ -# -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 8024302 -# @bug 8026037 -# @summary Clarify jar verifications -# - -if [ "${TESTJAVA}" = "" ] ; then - JAVAC_CMD=`which javac` - TESTJAVA=`dirname $JAVAC_CMD`/.. -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Windows_* ) - FS="\\" - ;; - * ) - FS="/" - ;; -esac - -KS=warnings.jks -JFILE=warnings.jar - -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ - -keystore $KS" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit" - -rm $KS 2> /dev/null - -LANG=C -export LANG - -echo 12345 > file - -ERR="" - -# Normal signer expiring on 2100-01-01 -$KT -alias s1 -dname CN=s1 -genkey -startdate 2000/01/01 -validity 36525 || ERR="$ERR keytool s1," -# Cert expiring soon, informational warning -$KT -alias s2 -dname CN=s2 -genkey -validity 100 || ERR="$ERR keytool s2," -# Cert expired, severe warning -$KT -alias s3 -dname CN=s3 -genkey -startdate -200d -validity 100 || ERR="$ERR keytool s3," - -# noTimestamp is informatiional warning and includes a date -$JAR cvf $JFILE file -$JARSIGNER $JFILE s1 > output1 || ERR="$ERR jarsigner s1," -$JARSIGNER -strict $JFILE s1 >> output1 || ERR="$ERR jarsigner s1 strict," -$JARSIGNER -verify $JFILE s1 >> output1 || ERR="$ERR jarsigner s1," -$JARSIGNER -verify -strict $JFILE s1 >> output1 || ERR="$ERR jarsigner s1 strict," - -cat output1 | grep Warning || ERR="$ERR s1 warning," -cat output1 | grep Error && ERR="$ERR s1 error," -cat output1 | grep timestamp | grep 2100-01-01 || ERR="$ERR s1 timestamp," -cat output1 | grep "with signer errors" && ERR="$ERR s1 err," - -# hasExpiringCert is informatiional warning -$JAR cvf $JFILE file -$JARSIGNER $JFILE s2 > output2 || ERR="$ERR jarsigner s2," -$JARSIGNER -strict $JFILE s2 >> output2 || ERR="$ERR jarsigner s2 strict," -$JARSIGNER -verify $JFILE s2 >> output2 || ERR="$ERR jarsigner s2," -$JARSIGNER -verify -strict $JFILE s2 >> output2 || ERR="$ERR jarsigner s2 strict," - -cat output2 | grep Warning || ERR="$ERR s2 warning," -cat output2 | grep Error && ERR="$ERR s2 error," -cat output2 | grep timestamp || ERR="$ERR s2 timestamp," -cat output2 | grep "will expire" || ERR="$ERR s2 expiring," -cat output2 | grep "with signer errors" && ERR="$ERR s2 err," - -# hasExpiredCert is severe warning -$JAR cvf $JFILE file -$JARSIGNER $JFILE s3 > output3 || ERR="$ERR jarsigner s3," -$JARSIGNER -strict $JFILE s3 > output3s && ERR="$ERR jarsigner s3 strict," -$JARSIGNER -verify $JFILE s3 >> output3 || ERR="$ERR jarsigner s3," -$JARSIGNER -verify -strict $JFILE s3 >> output3s && ERR="$ERR jarsigner s3 strict," - -# warning without -strict -cat output3 | grep Warning || ERR="$ERR s3 warning," -cat output3 | grep Error && ERR="$ERR s3 error," -cat output3 | grep "with signer errors" && ERR="$ERR s3 err," - -# error with -strict -cat output3s | grep Warning || ERR="$ERR s3s warning," -cat output3s | grep Error || ERR="$ERR s3s error," -cat output3s | grep "with signer errors" || ERR="$ERR s3 err," - -if [ "$ERR" = "" ]; then - exit 0 -else - echo "ERR is $ERR" - exit 1 -fi - - diff --git a/test/sun/security/tools/jarsigner/weaksize.sh b/test/sun/security/tools/jarsigner/weaksize.sh index f095645976f8ff5deebba38e3b3405e834eddceb..c5a06b5661cb44b32cc659522989a7ae69cb4a37 100644 --- a/test/sun/security/tools/jarsigner/weaksize.sh +++ b/test/sun/security/tools/jarsigner/weaksize.sh @@ -52,9 +52,9 @@ $KT -certreq -alias signer | \ $JAR cvf a.jar ks # We always trust a TrustedCertificateEntry -$JS a.jar ca || exit 1 +$JS a.jar ca | grep "chain is not validated" && exit 1 # An end-entity cert must follow algorithm constraints -$JS a.jar signer && exit 2 +$JS a.jar signer | grep "chain is not validated" || exit 2 exit 0