Write signature files to uber jars to for Oracle Java 17 verification

Update Gradle and Maven plugins to write an empty `META-INF/BOOT.SF`
file whenever there is a nested signed jar.

This update allows Oracle Java 17 to correctly verify the nested JARs.
The file is required because `JarVerifier` has code roughly equivalent
to:

	if (!jarManifestNameChecked && SharedSecrets
			.getJavaUtilZipFileAccess().getManifestName(jf, true) == null) {
    	throw new JarException("The JCE Provider " + jarURL.toString() +
    		" is not signed.");
	}

The `SharedSecrets.getJavaUtilZipFileAccess().getManifestName(jf, true)`
call ends up in `ZipFile.getManifestName(onlyIfSignatureRelatedFiles)`
which is a private method that we cannot override in our `NestedJarFile`
subclass. By writing an empty `.SF` file we ensure that the `Manifest`
is always returned because there are always "signature related files".

Fixes gh-28837
This commit is contained in:
Phillip Webb
2023-10-09 18:37:10 -07:00
parent fe752dedef
commit 33c5e1269a
17 changed files with 266 additions and 17 deletions

View File

@@ -16,12 +16,15 @@
package org.springframework.boot.gradle.tasks.bundling;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;
import java.util.jar.JarFile;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.TestTemplate;
import org.springframework.boot.gradle.junit.GradleCompatibility;
@@ -42,6 +45,15 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests {
super("bootJar", "BOOT-INF/lib/", "BOOT-INF/classes/", "BOOT-INF/");
}
@TestTemplate
void signed() throws Exception {
assertThat(this.gradleBuild.build("bootJar").task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
File jar = new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0];
try (JarFile jarFile = new JarFile(jar)) {
assertThat(jarFile.getEntry("META-INF/BOOT.SF")).isNotNull();
}
}
@TestTemplate
void whenAResolvableCopyOfAnUnresolvableConfigurationIsResolvedThenResolutionSucceeds() {
this.gradleBuild.expectDeprecationWarningsWithAtLeastVersion("8.0").build("build");