Creating a signed jar file

if printLoadMessages System.out.printlnLoading + url; InputStream is = url.openConnection.getInputStream ; buf = getClassBytesis; CodeSource cs = new CodeSourceurlBase, null; cl = defineClassname, buf, 0, buf.length, cs; return cl; } catch Exception e { System.out.printlnCant load + name + : + e; return null; } } Read a jar file, storing its classes into the classArray and the certificates of its signatures into the classIds. public void readJarFileString name { URL jarUrl = null; JarInputStream jis; JarEntry je; try { jarUrl = new URLurlBase, name; } catch MalformedURLException mue { System.out.printlnUnknown jar file + name; return; } if printLoadMessages System.out.printlnLoading jar file + jarUrl; try { jis = new JarInputStream jarUrl.openConnection.getInputStream ; } catch IOException ioe { System.out.printlnCant open jar file + jarUrl; return; } try { while je = jis.getNextJarEntry = null { String jarName = je.getName ; if jarName.endsWith.class loadClassBytesjis, jarName, je; else ignore it; it could be an image or audio file Really, these type of entries need to be saved for the resource methods; we leave that extension to the reader. jis.closeEntry ; } } catch IOException ioe { System.out.printlnBadly formatted jar file; } } private void loadClassBytesJarInputStream jis, String jarName, JarEntry je { if printLoadMessages System.out.println\t + jarName; BufferedInputStream jarBuf = new BufferedInputStreamjis; ByteArrayOutputStream jarOut = new ByteArrayOutputStream ; int b; try { while b = jarBuf.read = −1 jarOut.writeb; String className = jarName.substring0, jarName.length − 6; classArrays.putclassName, jarOut.toByteArray ; This returns the certificates from the signature file only if this class was signed. java.security.cert.Certificate c[] = je.getCertificates ; if c == null c = new java.security.cert.Certificate[0]; classIds.putclassName, c; } catch IOException ioe { System.out.printlnError reading entry + jarName; } } } Although its a long example, most of it simply deals with reading entries from the jar file. All that were left to do from a security perspective is obtain the array of signers when we read in each jar entry and then use that array of signers when we construct the code source we use to define the class. Remember that each file in a jar file may be signed by a different group of identities and that some may not be signed at all. This is why we must construct a new code source object for each signed class that was in the jar file.

12.3 Implementing a Signature Class

Now that weve seen how to use the Signature class, well look at how to implement our own class. The techniques well see here should be very familiar from our other examples of implementing an engine in the security provider architecture. In particular, since in Java 2 the Signature class extends its own SPI, we can implement a single class that extends the Signature class. To construct our subclass, we must use the following constructor: protected SignatureString algorithm This is the only constructor of the Signature class, so all subclasses of this class must use this constructor. The string passed to the constructor is the name that will be registered with the security provider. Once weve constructed our engine object, we must implement the following methods in it: protected abstract void engineInitVerifyPublicKey pk Initialize the object to prepare it to verify a digital signature. If the public key does not support the correct algorithm or is otherwise corrupted, an InvalidKeyException is thrown. protected abstract void engineInitSignPrivateKey pk Initialize the object to prepare it to create a digital signature. If the private key does not support the correct algorithm or is otherwise corrupted, an InvalidKeyException is thrown. protected abstract void engineUpdatebyte b protected abstract void engineUpdatebyte b[], int off, int len Add the given bytes to the data that is being accumulated for the signature. These methods are called by the update methods; they typically call the update method of a message digest held in the engine. If the engine has not been correctly initialized, a SignatureException is thrown. Chapter 12. Digital Signatures