From 7d45c667a5f4b67f284a3c3410b808ae11021c0a Mon Sep 17 00:00:00 2001 From: weijun Date: Mon, 25 Nov 2013 15:00:36 +0800 Subject: [PATCH] 8026067: Enhance signed jar verification Reviewed-by: ddehaven, ahgross, mullan --- .../classes/java/util/jar/JarVerifier.java | 20 ++------ .../sun/security/tools/jarsigner/Main.java | 20 +------- .../security/util/SignatureFileVerifier.java | 46 +++++++++++++++++++ 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/share/classes/java/util/jar/JarVerifier.java b/src/share/classes/java/util/jar/JarVerifier.java index 2b6b1451a..b20fac85b 100644 --- a/src/share/classes/java/util/jar/JarVerifier.java +++ b/src/share/classes/java/util/jar/JarVerifier.java @@ -687,6 +687,8 @@ class JarVerifier { } else { matchUnsigned = true; } + } else { + matchUnsigned = true; } } @@ -789,23 +791,7 @@ class JarVerifier { // true if file is part of the signature mechanism itself static boolean isSigningRelated(String name) { - name = name.toUpperCase(Locale.ENGLISH); - if (!name.startsWith("META-INF/")) { - return false; - } - name = name.substring(9); - if (name.indexOf('/') != -1) { - return false; - } - if (name.endsWith(".DSA") - || name.endsWith(".RSA") - || name.endsWith(".SF") - || name.endsWith(".EC") - || name.startsWith("SIG-") - || name.equals("MANIFEST.MF")) { - return true; - } - return false; + return SignatureFileVerifier.isSigningRelated(name); } private Enumeration unsignedEntryNames(JarFile jar) { diff --git a/src/share/classes/sun/security/tools/jarsigner/Main.java b/src/share/classes/sun/security/tools/jarsigner/Main.java index c24a68e71..76081d613 100644 --- a/src/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/share/classes/sun/security/tools/jarsigner/Main.java @@ -90,9 +90,6 @@ public class Main { private static final String META_INF = "META-INF/"; - // prefix for new signature-related files in META-INF directory - private static final String SIG_PREFIX = META_INF + "SIG-"; - private static final Class[] PARAM_STRING = { String.class }; private static final String NONE = "NONE"; @@ -1522,22 +1519,7 @@ public class Main { * . META-INF/*.EC */ private boolean signatureRelated(String name) { - String ucName = name.toUpperCase(Locale.ENGLISH); - if (ucName.equals(JarFile.MANIFEST_NAME) || - ucName.equals(META_INF) || - (ucName.startsWith(SIG_PREFIX) && - ucName.indexOf("/") == ucName.lastIndexOf("/"))) { - return true; - } - - if (ucName.startsWith(META_INF) && - SignatureFileVerifier.isBlockOrSF(ucName)) { - // .SF/.DSA/.RSA/.EC files in META-INF subdirs - // are not considered signature-related - return (ucName.indexOf("/") == ucName.lastIndexOf("/")); - } - - return false; + return SignatureFileVerifier.isSigningRelated(name); } Map cacheForSignerInfo = new IdentityHashMap<>(); diff --git a/src/share/classes/sun/security/util/SignatureFileVerifier.java b/src/share/classes/sun/security/util/SignatureFileVerifier.java index e84cc2c37..b8fb1e175 100644 --- a/src/share/classes/sun/security/util/SignatureFileVerifier.java +++ b/src/share/classes/sun/security/util/SignatureFileVerifier.java @@ -152,6 +152,52 @@ public class SignatureFileVerifier { return false; } + /** + * Yet another utility method used by JarVerifier and JarSigner + * to determine what files are signature related, which includes + * the MANIFEST, SF files, known signature block files, and other + * unknown signature related files (those starting with SIG- with + * an optional [A-Z0-9]{1,3} extension right inside META-INF). + * + * @param s file name + * @return true if the input file name is signature related + */ + public static boolean isSigningRelated(String name) { + name = name.toUpperCase(Locale.ENGLISH); + if (!name.startsWith("META-INF/")) { + return false; + } + name = name.substring(9); + if (name.indexOf('/') != -1) { + return false; + } + if (isBlockOrSF(name) || name.equals("MANIFEST.MF")) { + return true; + } else if (name.startsWith("SIG-")) { + // check filename extension + // see http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Digital_Signatures + // for what filename extensions are legal + int extIndex = name.lastIndexOf('.'); + if (extIndex != -1) { + String ext = name.substring(extIndex + 1); + // validate length first + if (ext.length() > 3 || ext.length() < 1) { + return false; + } + // then check chars, must be in [a-zA-Z0-9] per the jar spec + for (int index = 0; index < ext.length(); index++) { + char cc = ext.charAt(index); + // chars are promoted to uppercase so skip lowercase checks + if ((cc < 'A' || cc > 'Z') && (cc < '0' || cc > '9')) { + return false; + } + } + } + return true; // no extension is OK + } + return false; + } + /** get digest from cache */ private MessageDigest getDigest(String algorithm) -- GitLab