Skip to content

Commit

Permalink
8242060: Add revocation checking to jarsigner
Browse files Browse the repository at this point in the history
Reviewed-by: mullan, weijun
  • Loading branch information
Hai-May Chao committed May 7, 2020
1 parent 0ef6d1d commit 76507ee
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 4 deletions.
@@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -33,6 +33,7 @@
import java.util.*; import java.util.*;


import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.Event;
import sun.security.validator.Validator; import sun.security.validator.Validator;
import static sun.security.x509.PKIXExtensions.*; import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.*; import sun.security.x509.*;
Expand Down Expand Up @@ -246,6 +247,8 @@ private static X509CRL getCRL(URIName name) throws CertStoreException {
if (debug != null) { if (debug != null) {
debug.println("Trying to fetch CRL from DP " + uri); debug.println("Trying to fetch CRL from DP " + uri);
} }

Event.report("event.crl.check", uri.toString());
CertStore ucs = null; CertStore ucs = null;
try { try {
ucs = URICertStore.getInstance(new URICertStoreParameters(uri)); ucs = URICertStore.getInstance(new URICertStoreParameters(uri));
Expand Down
@@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -45,6 +45,7 @@


import sun.security.action.GetIntegerAction; import sun.security.action.GetIntegerAction;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.Event;
import sun.security.validator.Validator; import sun.security.validator.Validator;
import sun.security.x509.AccessDescription; import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension; import sun.security.x509.AuthorityInfoAccessExtension;
Expand Down Expand Up @@ -232,6 +233,8 @@ public static byte[] getOCSPBytes(List<CertId> certIds, URI responderURI,
if (debug != null) { if (debug != null) {
debug.println("connecting to OCSP service at: " + url); debug.println("connecting to OCSP service at: " + url);
} }

Event.report("event.ocsp.check", url.toString());
HttpURLConnection con = (HttpURLConnection)url.openConnection(); HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setConnectTimeout(CONNECT_TIMEOUT); con.setConnectTimeout(CONNECT_TIMEOUT);
con.setReadTimeout(CONNECT_TIMEOUT); con.setReadTimeout(CONNECT_TIMEOUT);
Expand Down
58 changes: 58 additions & 0 deletions src/java.base/share/classes/sun/security/util/Event.java
@@ -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);
}
}
}
Expand Up @@ -158,6 +158,7 @@ public static void main(String args[]) throws Exception {
boolean signManifest = true; // "sign" the whole manifest boolean signManifest = true; // "sign" the whole manifest
boolean externalSF = true; // leave the .SF out of the PKCS7 block boolean externalSF = true; // leave the .SF out of the PKCS7 block
boolean strict = false; // treat warnings as error boolean strict = false; // treat warnings as error
boolean revocationCheck = false; // Revocation check flag


// read zip entry raw bytes // read zip entry raw bytes
private String altSignerClass = null; private String altSignerClass = null;
Expand Down Expand Up @@ -293,6 +294,7 @@ public void run(String args[]) {
Arrays.fill(storepass, ' '); Arrays.fill(storepass, ' ');
storepass = null; storepass = null;
} }
Event.clearReportListener();
} }


if (strict) { if (strict) {
Expand Down Expand Up @@ -484,6 +486,8 @@ String[] parseArgs(String args[]) throws Exception {
// -help: legacy. // -help: legacy.
collator.compare(flags, "-help") == 0) { collator.compare(flags, "-help") == 0) {
fullusage(); fullusage();
} else if (collator.compare(flags, "-revCheck") == 0) {
revocationCheck = true;
} else { } else {
System.err.println( System.err.println(
rb.getString("Illegal.option.") + flags); rb.getString("Illegal.option.") + flags);
Expand Down Expand Up @@ -626,6 +630,9 @@ static void fullusage() {
System.out.println(rb.getString System.out.println(rb.getString
(".certs.display.certificates.when.verbose.and.verifying")); (".certs.display.certificates.when.verbose.and.verifying"));
System.out.println(); System.out.println();
System.out.println(rb.getString
(".certs.revocation.check"));
System.out.println();
System.out.println(rb.getString System.out.println(rb.getString
(".tsa.url.location.of.the.Timestamping.Authority")); (".tsa.url.location.of.the.Timestamping.Authority"));
System.out.println(); System.out.println();
Expand Down Expand Up @@ -2053,7 +2060,13 @@ void loadKeyStore(String keyStoreName, boolean prompt) {
.map(c -> new TrustAnchor(c, null)) .map(c -> new TrustAnchor(c, null))
.collect(Collectors.toSet()), .collect(Collectors.toSet()),
null); 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) { } catch (InvalidAlgorithmParameterException ex) {
// Only if tas is empty // Only if tas is empty
} }
Expand Down
Expand Up @@ -83,6 +83,8 @@ public class Resources extends java.util.ListResourceBundle {
" suboptions can be all, grouped or summary"}, " suboptions can be all, grouped or summary"},
{".certs.display.certificates.when.verbose.and.verifying", {".certs.display.certificates.when.verbose.and.verifying",
"[-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",
"[-tsa <url>] location of the Timestamping Authority"}, "[-tsa <url>] location of the Timestamping Authority"},
{".tsacert.alias.public.key.certificate.for.Timestamping.Authority", {".tsacert.alias.public.key.certificate.for.Timestamping.Authority",
Expand Down Expand Up @@ -310,6 +312,8 @@ public class Resources extends java.util.ListResourceBundle {
{"Cannot.find.environment.variable.", {"Cannot.find.environment.variable.",
"Cannot find environment variable: "}, "Cannot find environment variable: "},
{"Cannot.find.file.", "Cannot find file: "}, {"Cannot.find.file.", "Cannot find file: "},
{"event.ocsp.check", "Contacting OCSP server at %s ..."},
{"event.crl.check", "Downloading CRL from %s ..."},
}; };


/** /**
Expand Down
93 changes: 93 additions & 0 deletions test/jdk/sun/security/tools/jarsigner/EnableRevocation.java
@@ -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);
}
}
9 changes: 8 additions & 1 deletion test/jdk/sun/security/util/Resources/Usages.java
@@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -74,6 +74,9 @@ public class Usages {
static Pattern RB_GETSTRING = Pattern.compile( static Pattern RB_GETSTRING = Pattern.compile(
"(?m)rb[ \\n]*\\.getString[ \\n]*\\([ \\n]*\"(.*?)\"\\)"); "(?m)rb[ \\n]*\\.getString[ \\n]*\\([ \\n]*\"(.*?)\"\\)");


static Pattern EVENT_OCSP_CRL = Pattern.compile(
"Event\\.report\\(\"(.*?)\",");

// Command and Option enums in keytool // Command and Option enums in keytool
static Pattern KT_ENUM = Pattern.compile("\\n +[A-Z]+\\(.*\"(.*)\""); static Pattern KT_ENUM = Pattern.compile("\\n +[A-Z]+\\(.*\"(.*)\"");


Expand Down Expand Up @@ -116,6 +119,10 @@ public class Usages {
new sun.security.tools.jarsigner.Resources(), List.of( new sun.security.tools.jarsigner.Resources(), List.of(
new Pair("jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java", new Pair("jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java",
List.of(RB_GETSTRING)), 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", new Pair("java.base/share/classes/sun/security/tools/KeyStoreUtil.java",
List.of(RB_GETSTRING))), List.of(RB_GETSTRING))),
new sun.security.util.Resources(), List.of( new sun.security.util.Resources(), List.of(
Expand Down

0 comments on commit 76507ee

Please sign in to comment.