8242060: Add revocation checking to jarsigner
Reviewed-by: mullan, weijun
This commit is contained in:
parent
0ef6d1dff5
commit
76507eef63
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2020, 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
|
||||
@ -33,6 +33,7 @@ import javax.security.auth.x500.X500Principal;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.util.Event;
|
||||
import sun.security.validator.Validator;
|
||||
import static sun.security.x509.PKIXExtensions.*;
|
||||
import sun.security.x509.*;
|
||||
@ -246,6 +247,8 @@ public class DistributionPointFetcher {
|
||||
if (debug != null) {
|
||||
debug.println("Trying to fetch CRL from DP " + uri);
|
||||
}
|
||||
|
||||
Event.report("event.crl.check", uri.toString());
|
||||
CertStore ucs = null;
|
||||
try {
|
||||
ucs = URICertStore.getInstance(new URICertStoreParameters(uri));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2020, 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
|
||||
@ -45,6 +45,7 @@ import java.util.Map;
|
||||
|
||||
import sun.security.action.GetIntegerAction;
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.util.Event;
|
||||
import sun.security.validator.Validator;
|
||||
import sun.security.x509.AccessDescription;
|
||||
import sun.security.x509.AuthorityInfoAccessExtension;
|
||||
@ -232,6 +233,8 @@ public final class OCSP {
|
||||
if (debug != null) {
|
||||
debug.println("connecting to OCSP service at: " + url);
|
||||
}
|
||||
|
||||
Event.report("event.ocsp.check", url.toString());
|
||||
HttpURLConnection con = (HttpURLConnection)url.openConnection();
|
||||
con.setConnectTimeout(CONNECT_TIMEOUT);
|
||||
con.setReadTimeout(CONNECT_TIMEOUT);
|
||||
|
58
src/java.base/share/classes/sun/security/util/Event.java
Normal file
58
src/java.base/share/classes/sun/security/util/Event.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.security.util;
|
||||
|
||||
/**
|
||||
* This class implements an event model with services for reporter and listener.
|
||||
* Reporter uses report() method to generate an event.
|
||||
* Listener uses setReportListener() to register for listening to an event,
|
||||
* and uses clearReportListener() to unregister a listening session.
|
||||
* Listener should implement the event handling of the Reporter interface.
|
||||
*/
|
||||
public final class Event {
|
||||
private Event() {}
|
||||
|
||||
public interface Reporter {
|
||||
public void handle(String type, Object... args);
|
||||
}
|
||||
|
||||
private static Reporter reporter;
|
||||
public static void setReportListener(Reporter re) {
|
||||
reporter = re;
|
||||
}
|
||||
|
||||
public static void clearReportListener() {
|
||||
reporter = null;
|
||||
}
|
||||
|
||||
public static void report(String type, Object... args) {
|
||||
Reporter currentReporter = reporter;
|
||||
|
||||
if (currentReporter != null) {
|
||||
currentReporter.handle(type, args);
|
||||
}
|
||||
}
|
||||
}
|
@ -158,6 +158,7 @@ public class Main {
|
||||
boolean signManifest = true; // "sign" the whole manifest
|
||||
boolean externalSF = true; // leave the .SF out of the PKCS7 block
|
||||
boolean strict = false; // treat warnings as error
|
||||
boolean revocationCheck = false; // Revocation check flag
|
||||
|
||||
// read zip entry raw bytes
|
||||
private String altSignerClass = null;
|
||||
@ -293,6 +294,7 @@ public class Main {
|
||||
Arrays.fill(storepass, ' ');
|
||||
storepass = null;
|
||||
}
|
||||
Event.clearReportListener();
|
||||
}
|
||||
|
||||
if (strict) {
|
||||
@ -484,6 +486,8 @@ public class Main {
|
||||
// -help: legacy.
|
||||
collator.compare(flags, "-help") == 0) {
|
||||
fullusage();
|
||||
} else if (collator.compare(flags, "-revCheck") == 0) {
|
||||
revocationCheck = true;
|
||||
} else {
|
||||
System.err.println(
|
||||
rb.getString("Illegal.option.") + flags);
|
||||
@ -626,6 +630,9 @@ public class Main {
|
||||
System.out.println(rb.getString
|
||||
(".certs.display.certificates.when.verbose.and.verifying"));
|
||||
System.out.println();
|
||||
System.out.println(rb.getString
|
||||
(".certs.revocation.check"));
|
||||
System.out.println();
|
||||
System.out.println(rb.getString
|
||||
(".tsa.url.location.of.the.Timestamping.Authority"));
|
||||
System.out.println();
|
||||
@ -2053,7 +2060,13 @@ public class Main {
|
||||
.map(c -> new TrustAnchor(c, null))
|
||||
.collect(Collectors.toSet()),
|
||||
null);
|
||||
pkixParameters.setRevocationEnabled(false);
|
||||
|
||||
if (revocationCheck) {
|
||||
Security.setProperty("ocsp.enable", "true");
|
||||
System.setProperty("com.sun.security.enableCRLDP", "true");
|
||||
Event.setReportListener((t, o) -> System.out.println(String.format(rb.getString(t), o)));
|
||||
}
|
||||
pkixParameters.setRevocationEnabled(revocationCheck);
|
||||
} catch (InvalidAlgorithmParameterException ex) {
|
||||
// Only if tas is empty
|
||||
}
|
||||
|
@ -83,6 +83,8 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
" suboptions can be all, grouped or summary"},
|
||||
{".certs.display.certificates.when.verbose.and.verifying",
|
||||
"[-certs] display certificates when verbose and verifying"},
|
||||
{".certs.revocation.check",
|
||||
"[-revCheck] Enable certificate revocation check"},
|
||||
{".tsa.url.location.of.the.Timestamping.Authority",
|
||||
"[-tsa <url>] location of the Timestamping Authority"},
|
||||
{".tsacert.alias.public.key.certificate.for.Timestamping.Authority",
|
||||
@ -310,6 +312,8 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
{"Cannot.find.environment.variable.",
|
||||
"Cannot find environment variable: "},
|
||||
{"Cannot.find.file.", "Cannot find file: "},
|
||||
{"event.ocsp.check", "Contacting OCSP server at %s ..."},
|
||||
{"event.crl.check", "Downloading CRL from %s ..."},
|
||||
};
|
||||
|
||||
/**
|
||||
|
93
test/jdk/sun/security/tools/jarsigner/EnableRevocation.java
Normal file
93
test/jdk/sun/security/tools/jarsigner/EnableRevocation.java
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 8242060
|
||||
* @summary Add a test to enable revocation check in jarsigner
|
||||
* @library /test/lib
|
||||
*/
|
||||
|
||||
import jdk.test.lib.SecurityTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.util.JarUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class EnableRevocation {
|
||||
|
||||
static OutputAnalyzer kt(String cmd, String ks) throws Exception {
|
||||
return SecurityTools.keytool("-storepass changeit " + cmd +
|
||||
" -keystore " + ks);
|
||||
}
|
||||
|
||||
static void gencert(String owner, String cmd) throws Exception {
|
||||
kt("-certreq -alias " + owner + " -file tmp.req", "ks");
|
||||
kt("-gencert -infile tmp.req -outfile tmp.cert " + cmd, "ks");
|
||||
kt("-importcert -alias " + owner + " -file tmp.cert", "ks");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
kt("-genkeypair -keyalg rsa -alias ca -dname CN=CA -ext bc:c", "ks");
|
||||
kt("-genkeypair -keyalg rsa -alias ca1 -dname CN=CA1", "ks");
|
||||
kt("-genkeypair -keyalg rsa -alias e1 -dname CN=E1", "ks");
|
||||
|
||||
gencert("ca1", "-alias ca -ext san=dns:ca1 -ext bc:c " +
|
||||
"-ext crldp=URI:http://localhost:7000/crl.pem " +
|
||||
"-ext aia=ocsp:URI:http://localhost:7200");
|
||||
|
||||
gencert("e1", "-alias ca1 -ext san=dns:e1 " +
|
||||
"-ext crldp=URI:http://localhost:7000/crl.pem " +
|
||||
"-ext aia=ocsp:URI:http://localhost:7100");
|
||||
|
||||
JarUtils.createJarFile(Path.of("a.jar"), Path.of("."), Path.of("ks"));
|
||||
|
||||
//Signing with -revCheck option
|
||||
SecurityTools.jarsigner("-keystore ks -storepass changeit " +
|
||||
"-signedjar signeda.jar " +
|
||||
"-sigalg SHA256withRSA " +
|
||||
" a.jar e1 -revCheck")
|
||||
.shouldContain("Contacting OCSP server at")
|
||||
.shouldContain("Downloading CRL from")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
kt("-exportcert -alias ca -rfc -file cacert", "ks");
|
||||
kt("-importcert -noprompt -file cacert", "caks");
|
||||
|
||||
// Verifying with -revCheck option
|
||||
SecurityTools.jarsigner("-verify -certs signeda.jar " +
|
||||
"-keystore caks -storepass changeit -verbose -debug -revCheck")
|
||||
.shouldContain("Contacting OCSP server at")
|
||||
.shouldContain("Downloading CRL from")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
// Verifying with -revCheck and -strict options
|
||||
SecurityTools.jarsigner("-verify -certs signeda.jar " +
|
||||
"-keystore caks -storepass changeit " +
|
||||
"-strict -verbose -debug -revCheck")
|
||||
.shouldContain("Contacting OCSP server at")
|
||||
.shouldContain("Downloading CRL from")
|
||||
.shouldHaveExitValue(4);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2020, 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
|
||||
@ -74,6 +74,9 @@ public class Usages {
|
||||
static Pattern RB_GETSTRING = Pattern.compile(
|
||||
"(?m)rb[ \\n]*\\.getString[ \\n]*\\([ \\n]*\"(.*?)\"\\)");
|
||||
|
||||
static Pattern EVENT_OCSP_CRL = Pattern.compile(
|
||||
"Event\\.report\\(\"(.*?)\",");
|
||||
|
||||
// Command and Option enums in keytool
|
||||
static Pattern KT_ENUM = Pattern.compile("\\n +[A-Z]+\\(.*\"(.*)\"");
|
||||
|
||||
@ -116,6 +119,10 @@ public class Usages {
|
||||
new sun.security.tools.jarsigner.Resources(), List.of(
|
||||
new Pair("jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java",
|
||||
List.of(RB_GETSTRING)),
|
||||
new Pair("java.base/share/classes/sun/security/provider/certpath/OCSP.java",
|
||||
List.of(EVENT_OCSP_CRL)),
|
||||
new Pair("java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java",
|
||||
List.of(EVENT_OCSP_CRL)),
|
||||
new Pair("java.base/share/classes/sun/security/tools/KeyStoreUtil.java",
|
||||
List.of(RB_GETSTRING))),
|
||||
new sun.security.util.Resources(), List.of(
|
||||
|
Loading…
x
Reference in New Issue
Block a user