8026067: Enhance signed jar verification

Reviewed-by: ddehaven, ahgross, mullan
This commit is contained in:
Weijun Wang 2013-11-25 15:00:36 +08:00
parent 3f5d7a8e87
commit 4e372752a0
3 changed files with 50 additions and 36 deletions

View File

@ -676,6 +676,8 @@ class JarVerifier {
} else {
matchUnsigned = true;
}
} else {
matchUnsigned = true;
}
}
@ -778,23 +780,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<String> unsignedEntryNames(JarFile jar) {

View File

@ -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<CodeSigner,String> cacheForSignerInfo = new IdentityHashMap<>();

View File

@ -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)