OpenJDK / jdk / hs
changeset 23912:9eab25093a89
8026067: Enhance signed jar verification
Reviewed-by: ddehaven, ahgross, mullan
author | weijun |
---|---|
date | Mon, 25 Nov 2013 15:00:36 +0800 |
parents | f93d74f7d6fe |
children | 049a0df69b88 |
files | jdk/src/share/classes/java/util/jar/JarVerifier.java jdk/src/share/classes/sun/security/tools/jarsigner/Main.java jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java |
diffstat | 3 files changed, 50 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Wed Jan 22 14:59:33 2014 -0800 +++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Mon Nov 25 15:00:36 2013 +0800 @@ -676,6 +676,8 @@ } else { matchUnsigned = true; } + } else { + matchUnsigned = true; } } @@ -778,23 +780,7 @@ // 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<String> unsignedEntryNames(JarFile jar) {
--- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Wed Jan 22 14:59:33 2014 -0800 +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Mon Nov 25 15:00:36 2013 +0800 @@ -90,9 +90,6 @@ 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 @@ * . 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<CodeSigner,String> cacheForSignerInfo = new IdentityHashMap<>();
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Wed Jan 22 14:59:33 2014 -0800 +++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Mon Nov 25 15:00:36 2013 +0800 @@ -152,6 +152,52 @@ 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)