Skip to content

Commit

Permalink
Merge pull request #5267 from bjhargrave/jarsigner-fix
Browse files Browse the repository at this point in the history
jarsigner: Fix 2 bugs in the jarsigner support
  • Loading branch information
bjhargrave committed May 27, 2022
2 parents c621f12 + 0e783ef commit 02fa8fd
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 33 deletions.
49 changes: 20 additions & 29 deletions biz.aQute.bndlib.tests/test/test/JarSignerTest.java
@@ -1,21 +1,19 @@
package test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.util.jar.Manifest;

import org.junit.jupiter.api.Test;

import aQute.bnd.osgi.Builder;
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Processor;
import aQute.bnd.signing.JartoolSigner;
import aQute.bnd.test.jupiter.InjectTemporaryDirectory;
import aQute.lib.io.IO;
Expand All @@ -30,6 +28,7 @@ public class JarSignerTest {
public void testNoManifest(@InjectTemporaryDirectory
File tmpdir) throws Exception {
Builder b = new Builder();
b.setProperty("jarsigner", "jarsigner");
b.setProperty("-sign", "test");
b.setProperty(Constants.PLUGIN, JartoolSigner.class.getName()
+ ";keystore=testresources/keystore;keypass=testtest;storepass=testtest;sigfile=test");
Expand All @@ -44,9 +43,10 @@ public void testNoManifest(@InjectTemporaryDirectory

Jar jar2 = new Jar(tmp);
Manifest manifest = jar2.getManifest();
assertEquals("1.0", manifest.getMainAttributes()
.getValue("Manifest-Version"));
assertNotNull(manifest.getAttributes("WEB-INF/classes/org/osgi/framework/BundleContext.class"));
assertThat(manifest.getMainAttributes()).containsEntry(Name.MANIFEST_VERSION, "1.0");
assertThat(jar2.getResources()).containsKeys("META-INF/TEST.SF", "META-INF/TEST.EC");

assertThat(manifest.getAttributes("WEB-INF/classes/org/osgi/framework/BundleContext.class")).isNotNull();
}

@Test
Expand All @@ -63,11 +63,8 @@ public void testError() throws Exception {
Jar jar = new Jar(IO.getFile("testresources/test.jar"));
b.setJar(jar);
signer.sign(b, "test");
System.err.println(Processor.join(b.getErrors(), "\n"));
assertEquals(1, b.getErrors()
.size());
assertEquals(0, b.getWarnings()
.size());
assertThat(b.getErrors()).hasSize(1);
assertThat(b.getWarnings()).isEmpty();
}
}

Expand All @@ -79,7 +76,7 @@ public void testSimple() throws Exception {
properties.put("keypass", "testtest");
properties.put("storepass", "testtest");
properties.put("sigFile", "test");
properties.put("digestalg", "SHA-1");
properties.put("digestalg", "SHA-256");
signer.setProperties(properties);

Jar jar = new Jar(IO.getFile("testresources/test.jar"));
Expand All @@ -89,28 +86,22 @@ public void testSimple() throws Exception {
try (Builder b = new Builder()) {
b.setJar(jar);
signer.sign(b, "test");
System.err.println(Processor.join(b.getErrors(), "\n"));
System.err.println(Processor.join(b.getWarnings(), "\n"));
assertEquals(0, b.getErrors()
.size());
assertEquals(0, b.getWarnings()
.size());
assertNotNull(jar.getResource("META-INF/TEST.SF"));
assertThat(b.getErrors()).isEmpty();
assertThat(b.getWarnings()).isEmpty();
assertThat(jar.getResources()).containsKeys("META-INF/TEST.SF", "META-INF/TEST.EC");
Manifest m = jar.getManifest();

// Should have added 2 new resources: TEST.SF and TEST.DSA/RSA
assertEquals(names.size(), b.getJar()
.getResources()
.size() - 3);
// Should have added 2 new resources: TEST.SF and TEST.DSA/RSA/EC
assertThat(b.getJar()
.getResources()).hasSize(names.size() + 3);

Attributes a = m.getAttributes("aQute/rendezvous/DNS.class");
assertNotNull(a);
assertEquals("G0/1CIZlB4eIVyY8tU/ZfMCqZm4=", a.getValue("SHA-1-Digest"));
Name digestKey = new Name(properties.get("digestalg") + "-Digest");
assertThat(m.getAttributes("aQute/rendezvous/DNS.class")).containsEntry(digestKey,
"BMyZnHUVh1dDzBZSzaEyjRAZU+3pygawaasUDYLGEJ0=");

// Check if all resources are named
for (String name : names) {
System.err.println("name: " + name);
assertNotNull(m.getAttributes(name));
assertThat(m.getAttributes(name)).containsKey(digestKey);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions biz.aQute.bndlib.tests/testresources/certificate/gencert.sh
@@ -0,0 +1,2 @@
keytool -genkeypair -alias test -keyalg EC -sigalg SHA384withECDSA -validity 30000 -keystore ../keystore -keypass testtest -storepass testtest -dname "CN=John Smith,O=ACME Inc,OU=ACME Cert Authority,L=Austin,ST=Texas,C=US"
# keytool -exportcert -alias test -file cert.crt -storepass testtest -keystore ../keystore
Binary file modified biz.aQute.bndlib.tests/testresources/keystore
Binary file not shown.
25 changes: 21 additions & 4 deletions biz.aQute.bndlib/src/aQute/bnd/signing/JartoolSigner.java
Expand Up @@ -13,7 +13,10 @@
import aQute.bnd.osgi.Builder;
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Processor;
import aQute.bnd.service.Plugin;
import aQute.bnd.service.Registry;
import aQute.bnd.service.RegistryPlugin;
import aQute.bnd.service.SignerPlugin;
import aQute.bnd.stream.MapStream;
import aQute.lib.io.IO;
Expand All @@ -28,7 +31,7 @@
*/

@aQute.bnd.annotation.plugin.BndPlugin(name = "Signer", parameters = JartoolSigner.Config.class)
public class JartoolSigner implements Plugin, SignerPlugin {
public class JartoolSigner implements Plugin, SignerPlugin, RegistryPlugin {
private final static Logger logger = LoggerFactory.getLogger(JartoolSigner.class);

@interface Config {
Expand Down Expand Up @@ -64,6 +67,8 @@ public class JartoolSigner implements Plugin, SignerPlugin {
String tsacert;
String tsapolicyid;

private Processor processor;

@Override
public void setProperties(Map<String, String> map) {
if (map.containsKey("keystore"))
Expand Down Expand Up @@ -91,7 +96,12 @@ public void setProperties(Map<String, String> map) {
@Override
public void setReporter(Reporter processor) {}

private static Pattern EXTENSIONS_P = Pattern.compile(".*\\.(DSA|RSA|SF|MF)$");
@Override
public void setRegistry(Registry registry) {
processor = registry.getPlugin(Processor.class);
}

private static Pattern SIGNING_P = Pattern.compile("META-INF/([^/]*\\.(DSA|RSA|EC|SF|MF)|SIG-[^/]*)");

@Override
public void sign(Builder builder, String alias) throws Exception {
Expand All @@ -102,12 +112,19 @@ public void sign(Builder builder, String alias) throws Exception {
}

Jar jar = builder.getJar();
File tmp = File.createTempFile("signdjar", ".jar");
File tmp = File.createTempFile("signedjar", ".jar");
tmp.deleteOnExit();

jar.write(tmp);

Command command = new Command();
if ((path == null) || path.equals("jarsigner")) {
if (processor != null) {
path = processor.getJavaExecutable("jarsigner");
} else {
path = IO.getJavaExecutablePath("jarsigner");
}
}
command.add(path);
if (keystore != null) {
command.add("-keystore");
Expand Down Expand Up @@ -171,7 +188,7 @@ public void sign(Builder builder, String alias) throws Exception {
builder.addClose(signed);

MapStream.of(signed.getDirectory("META-INF"))
.filterKey(path -> EXTENSIONS_P.matcher(path)
.filterKey(path -> SIGNING_P.matcher(path)
.matches())
.forEachOrdered(jar::putResource);
jar.setDoNotTouchManifest();
Expand Down

0 comments on commit 02fa8fd

Please sign in to comment.