Skip to content

Commit 94e9513

Browse files
richard-dennehyelasticsearchmachinejfreden
authored
improve support for bytecode patching signed jars (#128613)
* improve support for bytecode patching signed jars * Update docs/changelog/128613.yaml --------- Co-authored-by: elasticsearchmachine <[email protected]> Co-authored-by: Johannes Freden Jansson <[email protected]>
1 parent 53bcc3e commit 94e9513

File tree

2 files changed

+31
-3
lines changed
  • build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/dependencies/patches
  • docs/changelog

2 files changed

+31
-3
lines changed

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/dependencies/patches/Utils.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424
import java.util.HexFormat;
2525
import java.util.Locale;
2626
import java.util.function.Function;
27+
import java.util.jar.Attributes;
2728
import java.util.jar.JarEntry;
2829
import java.util.jar.JarFile;
2930
import java.util.jar.JarOutputStream;
31+
import java.util.jar.Manifest;
3032
import java.util.stream.Collectors;
3133

3234
import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
@@ -60,6 +62,10 @@ public String toString() {
6062
}
6163
}
6264

65+
public static void patchJar(File inputJar, File outputJar, Collection<PatcherInfo> patchers) {
66+
patchJar(inputJar, outputJar, patchers, false);
67+
}
68+
6369
/**
6470
* Patches the classes in the input JAR file, using the collection of patchers. Each patcher specifies a target class (its jar entry
6571
* name) and the SHA256 digest on the class bytes.
@@ -69,8 +75,11 @@ public String toString() {
6975
* @param inputFile the JAR file to patch
7076
* @param outputFile the output (patched) JAR file
7177
* @param patchers list of patcher info (classes to patch (jar entry name + optional SHA256 digest) and ASM visitor to transform them)
78+
* @param unsignJar whether to remove class signatures from the JAR Manifest; set this to true when patching a signed JAR,
79+
* otherwise the patched classes will fail to load at runtime due to mismatched signatures.
80+
* @see <a href="https://docs.oracle.com/javase/tutorial/deployment/jar/intro.html">Understanding Signing and Verification</a>
7281
*/
73-
public static void patchJar(File inputFile, File outputFile, Collection<PatcherInfo> patchers) {
82+
public static void patchJar(File inputFile, File outputFile, Collection<PatcherInfo> patchers, boolean unsignJar) {
7483
var classPatchers = patchers.stream().collect(Collectors.toMap(PatcherInfo::jarEntryName, Function.identity()));
7584
var mismatchedClasses = new ArrayList<MismatchInfo>();
7685
try (JarFile jarFile = new JarFile(inputFile); JarOutputStream jos = new JarOutputStream(new FileOutputStream(outputFile))) {
@@ -101,9 +110,23 @@ public static void patchJar(File inputFile, File outputFile, Collection<PatcherI
101110
);
102111
}
103112
} else {
104-
// Read the entry's data and write it to the new JAR
105113
try (InputStream is = jarFile.getInputStream(entry)) {
106-
is.transferTo(jos);
114+
if (unsignJar && entryName.equals("META-INF/MANIFEST.MF")) {
115+
var manifest = new Manifest(is);
116+
for (var manifestEntry : manifest.getEntries().entrySet()) {
117+
var nonSignatureAttributes = new Attributes();
118+
for (var attribute : manifestEntry.getValue().entrySet()) {
119+
if (attribute.getKey().toString().endsWith("Digest") == false) {
120+
nonSignatureAttributes.put(attribute.getKey(), attribute.getValue());
121+
}
122+
}
123+
manifestEntry.setValue(nonSignatureAttributes);
124+
}
125+
manifest.write(jos);
126+
} else if (unsignJar == false || entryName.matches("META-INF/.*\\.SF") == false) {
127+
// Read the entry's data and write it to the new JAR
128+
is.transferTo(jos);
129+
}
107130
}
108131
}
109132
jos.closeEntry();

docs/changelog/128613.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 128613
2+
summary: Improve support for bytecode patching signed jars
3+
area: Infra/Core
4+
type: enhancement
5+
issues: []

0 commit comments

Comments
 (0)