Skip to content
Permalink
Browse files

8242060: Add revocation checking to jarsigner

Reviewed-by: mullan, weijun
  • Loading branch information
Hai-May Chao
Hai-May Chao committed May 7, 2020
1 parent 0ef6d1d commit 76507eef639c41bffe9a4bb2b8a5083291f41383
@@ -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 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 @@ private static X509CRL getCRL(URIName name) throws CertStoreException {
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 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 @@ static OCSPResponse check(List<CertId> certIds, URI responderURI,
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);
@@ -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 static void main(String args[]) throws Exception {
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 void run(String args[]) {
Arrays.fill(storepass, ' ');
storepass = null;
}
Event.clearReportListener();
}

if (strict) {
@@ -484,6 +486,8 @@ public void run(String args[]) {
// -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 @@ static void fullusage() {
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 @@ void loadKeyStore(String keyStoreName, boolean prompt) {
.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 @@
" 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 @@
{"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 ..."},
};

/**
@@ -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 @@
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 @@
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(

0 comments on commit 76507ee

Please sign in to comment.
You can’t perform that action at this time.