use of aQute.bnd.osgi.EmbeddedResource in project bnd by bndtools.
the class Signer method signJar.
public void signJar(Jar jar) {
if (digestNames == null || digestNames.length == 0)
error("Need at least one digest algorithm name, none are specified");
if (keystoreFile == null || !keystoreFile.getAbsoluteFile().exists()) {
error("No such keystore file: %s", keystoreFile);
return;
}
if (alias == null) {
error("Private key alias not set for signing");
return;
}
MessageDigest[] digestAlgorithms = new MessageDigest[digestNames.length];
getAlgorithms(digestNames, digestAlgorithms);
try {
Manifest manifest = jar.getManifest();
manifest.getMainAttributes().putValue("Signed-By", "Bnd");
// Create a new manifest that contains the
// Name parts with the specified digests
ByteArrayOutputStream o = new ByteArrayOutputStream();
manifest.write(o);
doManifest(jar, digestNames, digestAlgorithms, o);
o.flush();
byte[] newManifestBytes = o.toByteArray();
jar.putResource("META-INF/MANIFEST.MF", new EmbeddedResource(newManifestBytes, 0));
// Use the bytes from the new manifest to create
// a signature file
byte[] signatureFileBytes = doSignatureFile(digestNames, digestAlgorithms, newManifestBytes);
jar.putResource("META-INF/BND.SF", new EmbeddedResource(signatureFileBytes, 0));
// Now we must create an RSA signature
// this requires the private key from the keystore
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore.PrivateKeyEntry privateKeyEntry = null;
try (InputStream keystoreInputStream = IO.stream(keystoreFile)) {
char[] pw = password == null ? new char[0] : password.toCharArray();
keystore.load(keystoreInputStream, pw);
keystoreInputStream.close();
privateKeyEntry = (PrivateKeyEntry) keystore.getEntry(alias, new KeyStore.PasswordProtection(pw));
} catch (Exception e) {
exception(e, "Not able to load the private key from the given keystore(%s) with alias %s", keystoreFile.getAbsolutePath(), alias);
return;
}
PrivateKey privateKey = privateKeyEntry.getPrivateKey();
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(signatureFileBytes);
signature.sign();
// TODO, place the SF in a PCKS#7 structure ...
// no standard class for this? The following
// is an idea but we will to have do ASN.1 BER
// encoding ...
ByteArrayOutputStream tmpStream = new ByteArrayOutputStream();
jar.putResource("META-INF/BND.RSA", new EmbeddedResource(tmpStream.toByteArray(), 0));
} catch (Exception e) {
exception(e, "During signing: %s", e);
}
}
use of aQute.bnd.osgi.EmbeddedResource in project bnd by bndtools.
the class ProjectLauncherImpl method executable.
/**
* Create a standalone executable. All entries on the runpath are rolled out
* into the JAR and the runbundles are copied to a directory in the jar. The
* launcher will see that it starts in embedded mode and will automatically
* detect that it should load the bundles from inside. This is drive by the
* launcher.embedded flag.
*
* @throws Exception
*/
@Override
public Jar executable() throws Exception {
// TODO use constants in the future
Parameters packageHeader = OSGiHeader.parseHeader(getProject().getProperty("-package"));
boolean useShas = packageHeader.containsKey("jpm");
logger.debug("useShas {} {}", useShas, packageHeader);
Jar jar = new Jar(getProject().getName());
Builder b = new Builder();
getProject().addClose(b);
if (!getProject().getIncludeResource().isEmpty()) {
b.setIncludeResource(getProject().getIncludeResource().toString());
b.setProperty(Constants.RESOURCEONLY, "true");
b.build();
if (b.isOk()) {
jar.addAll(b.getJar());
}
getProject().getInfo(b);
}
List<String> runpath = getRunpath();
Set<String> runpathShas = new LinkedHashSet<String>();
Set<String> runbundleShas = new LinkedHashSet<String>();
List<String> classpath = new ArrayList<String>();
for (String path : runpath) {
logger.debug("embedding runpath {}", path);
File file = new File(path);
if (file.isFile()) {
if (useShas) {
String sha = SHA1.digest(file).asHex();
runpathShas.add(sha + ";name=\"" + file.getName() + "\"");
} else {
String newPath = nonCollidingPath(file, jar);
jar.putResource(newPath, new FileResource(file));
classpath.add(newPath);
}
}
}
// Copy the bundles to the JAR
List<String> runbundles = (List<String>) getRunBundles();
List<String> actualPaths = new ArrayList<String>();
for (String path : runbundles) {
logger.debug("embedding run bundles {}", path);
File file = new File(path);
if (!file.isFile())
getProject().error("Invalid entry in -runbundles %s", file);
else {
if (useShas) {
String sha = SHA1.digest(file).asHex();
runbundleShas.add(sha + ";name=\"" + file.getName() + "\"");
actualPaths.add("${JPMREPO}/" + sha);
} else {
String newPath = nonCollidingPath(file, jar);
jar.putResource(newPath, new FileResource(file));
actualPaths.add(newPath);
}
}
}
LauncherConstants lc = getConstants(actualPaths, true);
lc.embedded = !useShas;
// cannot use local info
lc.storageDir = null;
final Properties p = lc.getProperties(new UTF8Properties());
ByteArrayOutputStream bout = new ByteArrayOutputStream();
p.store(bout, "");
jar.putResource(LauncherConstants.DEFAULT_LAUNCHER_PROPERTIES, new EmbeddedResource(bout.toByteArray(), 0L));
Manifest m = new Manifest();
Attributes main = m.getMainAttributes();
for (Entry<Object, Object> e : getProject().getFlattenedProperties().entrySet()) {
String key = (String) e.getKey();
if (key.length() > 0 && Character.isUpperCase(key.charAt(0)))
main.putValue(key, (String) e.getValue());
}
Instructions instructions = new Instructions(getProject().getProperty(Constants.REMOVEHEADERS));
Collection<Object> result = instructions.select(main.keySet(), false);
main.keySet().removeAll(result);
if (useShas) {
logger.debug("Use JPM launcher");
m.getMainAttributes().putValue("Main-Class", JPM_LAUNCHER_FQN);
m.getMainAttributes().putValue("JPM-Classpath", Processor.join(runpathShas));
m.getMainAttributes().putValue("JPM-Runbundles", Processor.join(runbundleShas));
URLResource jpmLauncher = new URLResource(this.getClass().getResource("/" + JPM_LAUNCHER));
jar.putResource(JPM_LAUNCHER, jpmLauncher);
doStart(jar, JPM_LAUNCHER_FQN);
} else {
logger.debug("Use Embedded launcher");
m.getMainAttributes().putValue("Main-Class", EMBEDDED_LAUNCHER_FQN);
m.getMainAttributes().putValue(EmbeddedLauncher.EMBEDDED_RUNPATH, Processor.join(classpath));
URLResource embeddedLauncher = new URLResource(this.getClass().getResource("/" + EMBEDDED_LAUNCHER));
jar.putResource(EMBEDDED_LAUNCHER, embeddedLauncher);
doStart(jar, EMBEDDED_LAUNCHER_FQN);
}
if (getProject().getProperty(Constants.DIGESTS) != null)
jar.setDigestAlgorithms(getProject().getProperty(Constants.DIGESTS).trim().split("\\s*,\\s*"));
else
jar.setDigestAlgorithms(new String[] { "SHA-1", "MD-5" });
jar.setManifest(m);
cleanup();
return jar;
}
use of aQute.bnd.osgi.EmbeddedResource in project bnd by bndtools.
the class BuilderTest method testImportVersionSource.
/**
* Test where the version comes from: Manifest or packageinfo
*
* @throws Exception
*/
public static void testImportVersionSource() throws Exception {
Jar fromManifest = new Jar("manifestsource");
Jar fromPackageInfo = new Jar("packageinfosource");
Jar fromBoth = new Jar("both");
try {
Manifest mms = new Manifest();
mms.getMainAttributes().putValue("Export-Package", "org.osgi.service.event; version=100");
fromManifest.setManifest(mms);
fromPackageInfo.putResource("org/osgi/service/event/packageinfo", new EmbeddedResource("version 99".getBytes(), 0));
Manifest mboth = new Manifest();
mboth.getMainAttributes().putValue("Export-Package", "org.osgi.service.event; version=101");
fromBoth.putResource("org/osgi/service/event/packageinfo", new EmbeddedResource("version 199".getBytes(), 0));
fromBoth.setManifest(mboth);
// Only version in manifest
Builder bms = new Builder();
try {
bms.addClasspath(fromManifest);
bms.setProperty("Import-Package", "org.osgi.service.event");
bms.build();
assertTrue(bms.check("The JAR is empty"));
String s = bms.getImports().getByFQN("org.osgi.service.event").get("version");
assertEquals("[100.0,101)", s);
// Only version in packageinfo
Builder bpinfos = new Builder();
try {
bpinfos.addClasspath(fromPackageInfo);
bpinfos.setProperty("Import-Package", "org.osgi.service.event");
bpinfos.build();
assertTrue(bms.check());
s = bpinfos.getImports().getByFQN("org.osgi.service.event").get("version");
assertEquals("[99.0,100)", s);
// Version in manifest + packageinfo
Builder bboth = new Builder();
try {
bboth.addClasspath(fromBoth);
bboth.setProperty("Import-Package", "org.osgi.service.event");
bboth.build();
assertTrue(bms.check());
s = bboth.getImports().getByFQN("org.osgi.service.event").get("version");
assertEquals("[101.0,102)", s);
} finally {
bboth.close();
}
} finally {
bpinfos.close();
}
} finally {
bms.close();
}
} finally {
fromManifest.close();
fromPackageInfo.close();
fromBoth.close();
}
}
use of aQute.bnd.osgi.EmbeddedResource in project bnd by bndtools.
the class JarTest method testDeletePrefix.
public void testDeletePrefix() {
Resource r = new EmbeddedResource(new byte[1], 0);
Jar jar = new Jar("test");
jar.putResource("META-INF/maven/org/osgi/test/test.pom", r);
jar.putResource("META-INF/maven/org/osgi/test/test.properties", r);
jar.putResource("META-INF/MANIFEST.MF", r);
jar.putResource("com/example/foo.jar", r);
assertTrue(jar.getDirectories().containsKey("META-INF/maven/org/osgi/test"));
assertTrue(jar.getDirectories().containsKey("META-INF/maven"));
jar.removePrefix("META-INF/maven/");
assertNotNull(jar.getResource("META-INF/MANIFEST.MF"));
assertNotNull(jar.getResource("com/example/foo.jar"));
assertNull(jar.getResource("META-INF/maven/org/osgi/test/test.pom"));
assertNull(jar.getResource("META-INF/maven/org/osgi/test/test.properties"));
assertFalse(jar.getDirectories().containsKey("META-INF/maven"));
assertFalse(jar.getDirectories().containsKey("META-INF/maven/org/osgi/test"));
}
use of aQute.bnd.osgi.EmbeddedResource in project bnd by bndtools.
the class SubsystemExporter method export.
@Override
public Map.Entry<String, Resource> export(String type, final Project project, Map<String, String> options) throws Exception {
Jar jar = new Jar(".");
project.addClose(jar);
Manifest manifest = new Manifest();
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
manifest.getMainAttributes().putValue("Subsystem-ManifestVersion", "1");
List<Container> distro = project.getBundles(Strategy.LOWEST, project.getProperty(Constants.DISTRO), Constants.DISTRO);
List<File> distroFiles = getBundles(distro, project);
List<File> files = getBundles(project.getRunbundles(), project);
MultiMap<String, Attrs> imports = new MultiMap<String, Attrs>();
MultiMap<String, Attrs> exports = new MultiMap<String, Attrs>();
Parameters requirements = new Parameters();
Parameters capabilities = new Parameters();
for (File file : files) {
Domain domain = Domain.domain(file);
String bsn = domain.getBundleSymbolicName().getKey();
String version = domain.getBundleVersion();
for (Entry<String, Attrs> e : domain.getImportPackage().entrySet()) {
imports.add(e.getKey(), e.getValue());
}
for (Entry<String, Attrs> e : domain.getExportPackage().entrySet()) {
exports.add(e.getKey(), e.getValue());
}
String path = bsn + "-" + version + ".jar";
jar.putResource(path, new FileResource(file));
}
headers(project, manifest.getMainAttributes());
set(manifest.getMainAttributes(), SUBSYSTEM_TYPE, OSGI_SUBSYSTEM_FEATURE);
String ssn = project.getName();
Collection<String> bsns = project.getBsns();
if (bsns.size() > 0) {
ssn = bsns.iterator().next();
}
set(manifest.getMainAttributes(), SUBSYSTEM_SYMBOLIC_NAME, ssn);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
manifest.write(bout);
jar.putResource(OSGI_INF_SUBSYSTEM_MF, new EmbeddedResource(bout.toByteArray(), 0));
final JarResource jarResource = new JarResource(jar);
final String name = ssn + ".esa";
return new Map.Entry<String, Resource>() {
@Override
public String getKey() {
return name;
}
@Override
public Resource getValue() {
return jarResource;
}
@Override
public Resource setValue(Resource arg0) {
throw new UnsupportedOperationException();
}
};
}
Aggregations