Changed how packed actions are saved (in the zip extra data field now). fixed lpgl hashing method

This commit is contained in:
nathan 2014-12-16 23:51:55 +01:00
parent 1d8a329235
commit ff8c718a6b

View File

@ -169,76 +169,91 @@ public class Crypto {
} }
// CUSTOM_HEADER USE // CUSTOM_HEADER USE
private static byte[] CUSTOM_HEADER = new byte[] {-54, -98, 98, 120}; private static byte[] CUSTOM_HEADER = new byte[] {-2, -54, -54, -98};
/** /**
* Specifically, to return the hash of the ALL files/directories inside the jar, minus the action specified (LGPL) files. * Specifically, to return the hash of the ALL files/directories inside the jar, minus the action specified (LGPL) files.
*/ */
public static final byte[] hashJarContentsExcludeAction(JarFile jarFile, Digest digest, int action) throws IOException { public static final byte[] hashJarContentsExcludeAction(File jarDestFilename, Digest digest, int action) throws IOException {
Enumeration<JarEntry> jarElements = jarFile.entries(); JarFile jarDestFile = new JarFile(jarDestFilename);
boolean okToHash = false; try {
boolean hasAction = false; Enumeration<JarEntry> jarElements = jarDestFile.entries();
byte[] buffer = new byte[2048];
int read = 0;
digest.reset();
while (jarElements.hasMoreElements()) { boolean okToHash = false;
JarEntry jarEntry = jarElements.nextElement(); boolean hasAction = false;
String name = jarEntry.getName(); byte[] buffer = new byte[2048];
okToHash = !jarEntry.isDirectory(); int read = 0;
digest.reset();
if (!okToHash) { while (jarElements.hasMoreElements()) {
continue; JarEntry jarEntry = jarElements.nextElement();
} String name = jarEntry.getName();
okToHash = !jarEntry.isDirectory();
okToHash = true; if (!okToHash) {
hasAction = false; continue;
byte[] extraData = jarEntry.getExtra();
if (extraData != null && extraData.length > 4) {
for (int i = 0; i < CUSTOM_HEADER.length; i++) {
if (extraData[i] != CUSTOM_HEADER[i]) {
// can hash if we don't have an action assigned (LGPL will ALWAYS have an action assigned)
okToHash = false;
break;
}
} }
// this means we matched our header // data with NO extra data will NOT BE HASHED
int fileAction = 0; // data that matches our action bitmask WILL NOT BE HASHED
if (okToHash) { okToHash = false;
hasAction = false;
byte[] extraData = jarEntry.getExtra();
if (extraData == null || extraData.length == 0) {
okToHash = false;
} else if (extraData.length >= 4) {
for (int i = 0; i < CUSTOM_HEADER.length; i++) {
if (extraData[i] != CUSTOM_HEADER[i]) {
throw new RuntimeException("Unexpected extra data in zip assigned. Aborting");
}
}
// this means we matched our header
if (extraData[4] > 0) { if (extraData[4] > 0) {
hasAction = true; hasAction = true;
// we have an ACTION describing how it was compressed, etc // we have an ACTION describing how it was compressed, etc
fileAction = LittleEndian.Int_.fromBytes(new byte[] {extraData[5], extraData[6], extraData[7], extraData[8]}); int fileAction = LittleEndian.Int_.fromBytes(new byte[] {extraData[5], extraData[6], extraData[7], extraData[8]});
if ((fileAction & action) != action) {
okToHash = true;
}
} else {
okToHash = true;
}
} else {
throw new RuntimeException("Unexpected extra data in zip assigned. Aborting");
}
// skips hashing lgpl files. (technically, whatever our action bitmask is...)
// we want to hash everything BY DEFAULT. we ALSO want to hash the NAME, LOAD ACTION TYPE, and the contents
if (okToHash) {
// System.err.println("HASHING: " + name);
// hash the file name
byte[] bytes = name.getBytes(OS.US_ASCII);
digest.update(bytes, 0, bytes.length);
if (hasAction) {
// hash the action - since we don't want to permit anyone to change this after we sign the file
digest.update(extraData, 5, 4);
} }
if ((fileAction & action) == action) { // hash the contents
okToHash = false; InputStream inputStream = jarDestFile.getInputStream(jarEntry);
while ((read = inputStream.read(buffer)) > 0) {
digest.update(buffer, 0, read);
} }
inputStream.close();
} else {
// System.err.println("Skipping: " + name);
} }
} }
} catch (Exception e) {
// skips hashing lgpl files. (technically, whatever our action bitmask is...) throw new RuntimeException("Unexpected extra data in zip assigned. Aborting");
// we want to hash everything BY DEFAULT. we ALSO want to hash the NAME, LOAD ACTION TYPE, and the contents } finally {
if (okToHash) { jarDestFile.close();
// hash the file name
byte[] bytes = name.getBytes(OS.US_ASCII);
digest.update(bytes, 0, bytes.length);
if (hasAction) {
// hash the action
digest.update(extraData, 5, 4);
}
// hash the contents
InputStream inputStream = jarFile.getInputStream(jarEntry);
while ((read = inputStream.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
inputStream.close();
}
} }
byte[] digestBytes = new byte[digest.getDigestSize()]; byte[] digestBytes = new byte[digest.getDigestSize()];