public static boolean extractJarDir(String jarfile, String outfile) throws Exception { long filesize = new File(jarfile).length(); JarInputStream jar = new JarInputStream(new FileInputStream(jarfile)); // while (true) { // JarEntry jarentry = (JarEntry)jar.getNextJarEntry(); // if (jarentry==null) break; // String maindir = jarentry.getName(); // // get rid of "./" and "/" prefix // if (maindir.startsWith(".")) // maindir = maindir.substring(1); // if (maindir.startsWith(File.separator)) // maindir = maindir.substring(1); // // Find manifest // System.out.println(maindir); // if (maindir.equals("META-INF/MANIFEST.MF")) { // java.io.InputStream ins = jar; java.io.FileOutputStream outs = new java.io.FileOutputStream(outfile); Manifest man = jar.getManifest(); if (man == null) return false; man.write(outs); byte[] buf = ("MIDlet-Jar-Size: " + filesize).getBytes(); outs.write(buf, 0, buf.length); outs.close(); // // copy buffered (is a lot faster than one byte at a time) // byte[] buf = new byte[8192]; // int total_bytes=0; // while (true) { // //outs.write(ins.read()); // int len = ins.read(buf); // if (len < 0) break; // outs.write(buf,0,len); // total_bytes += len; // } // buf = ("MIDlet-Jar-Size: "+total_bytes).getBytes(); // outs.write(buf,0,buf.length); // outs.close(); // //ins.close(); // } // } // return false; // remove empty lines from the generated jad which may have been // introduced by manifest write. // some systems have trouble with empty lines List<String> lines = new ArrayList<String>(); BufferedReader in = new BufferedReader(new FileReader(outfile)); while (true) { String line = in.readLine(); if (line == null) break; lines.add(line); } in.close(); PrintWriter outp = new PrintWriter(outfile); for (String s : lines) { if (s.trim().equals("")) continue; outp.println(s); } outp.close(); return true; }
/** hardcoded imports */ public static void testHardcodedImports() throws Exception { Builder b = new Builder(); b.addClasspath(IO.getFile("jar/osgi.jar")); b.setProperty("-versionpolicy", "${range;[==,+)}"); b.setProperty("Private-Package", "org.objectweb.asm"); b.setProperty("Import-Package", "org.osgi.framework,org.objectweb.asm,abc;version=2.0.0,*"); b.build(); Manifest m = b.getJar().getManifest(); m.write(System.err); String s = b.getImports().getByFQN("org.objectweb.asm").get("version"); assertNull(s); s = b.getImports().getByFQN("abc").get("version"); assertEquals("2.0.0", s); s = b.getImports().getByFQN("org.osgi.framework").get("version"); assertEquals("[1.3,2)", s); }
/** * Tests if the implementation of the EventHandler (which is marked as a ConsumerType) causes the * import of the api package to use the consumer version policy. */ public static void testConsumerType() throws Exception { Builder a = new Builder(); a.addClasspath(new File("bin")); a.setPrivatePackage("test.versionpolicy.uses"); a.setExportPackage("test.versionpolicy.api"); a.setProperty("build", "123"); Jar jar = a.build(); assertTrue(a.check()); Manifest m = jar.getManifest(); m.write(System.err); Domain d = Domain.domain(m); Parameters parameters = d.getImportPackage(); Attrs attrs = parameters.get("test.versionpolicy.api"); assertNotNull(attrs); assertEquals("[1.2,2)", attrs.get("version")); }
/** * Test if the implementation of "AnnotatedProviderInterface", which is annotated with OSGi * R6 @ProviderType, causes import of the api package to use the provider version policy */ public static void testProviderTypeR6() throws Exception { Builder b = new Builder(); b.addClasspath(new File("bin")); b.setPrivatePackage("test.versionpolicy.implemented.osgi"); b.setProperty("build", "123"); Jar jar = b.build(); assertTrue(b.check()); Manifest m = jar.getManifest(); m.write(System.err); Domain d = Domain.domain(m); Parameters params = d.getImportPackage(); Attrs attrs = params.get("test.version.annotations.osgi"); assertNotNull(attrs); assertEquals("[1.2,1.3)", attrs.get("version")); }
/** * Tests if the implementation of the EventAdmin (which is marked as a ProviderType) causes the * import of the api package to use the provider version policy. */ public static void testProviderType() throws Exception { Builder a = new Builder(); a.addClasspath(new File("bin")); a.setPrivatePackage("test.versionpolicy.implemented"); a.setExportPackage("test.versionpolicy.api"); a.setImportPackage("test.versionpolicy.api"); // what changed so this is // not automatically // added? a.setProperty("build", "123"); Jar jar = a.build(); assertTrue(a.check()); Manifest m = jar.getManifest(); m.write(System.err); Domain d = Domain.domain(m); Parameters parameters = d.getImportPackage(); Attrs attrs = parameters.get("test.versionpolicy.api"); assertNotNull(attrs); assertEquals("[1.2,1.3)", attrs.get("version")); }
/** Check implementation version policy. Uses the package test.versionpolicy.(uses|implemented) */ static void assertPolicy(String pack, String type) throws Exception { Builder a = new Builder(); a.addClasspath(new File("bin")); a.setProperty("Export-Package", "test.versionpolicy.api"); Jar jar = a.build(); Builder b = new Builder(); b.addClasspath(jar); b.addClasspath(new File("bin")); b.setProperty("-versionpolicy-impl", "IMPL"); b.setProperty("-versionpolicy-uses", "USES"); b.setProperty("Private-Package", pack); b.build(); Manifest m = b.getJar().getManifest(); m.write(System.err); Map<String, String> map = b.getImports().getByFQN("test.versionpolicy.api"); assertNotNull(map); // String s = map.get(Constants.IMPLEMENTED_DIRECTIVE); // assertEquals("true", s); Parameters mp = Processor.parseHeader(m.getMainAttributes().getValue("Import-Package"), null); assertEquals(type, mp.get("test.versionpolicy.api").get("version")); }
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: " + 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; java.io.FileInputStream keystoreInputStream = null; try { keystoreInputStream = new java.io.FileInputStream(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) { error( "No able to load the private key from the give keystore(" + keystoreFile.getAbsolutePath() + ") with alias " + alias + " : " + e); return; } finally { IO.close(keystoreInputStream); } 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) { error("During signing: " + e); } }