Java’s sandbox model for applet security is often too restrictive to be useful. For example, the sandbox model doesn’t allow applets to write to the user’s local computer, even if there is a valid reason to do so. Code signing is a way to step out of the sandbox. The idea behind code signing is that if you trust the person vouching for a piece of code, you may be willing to take a risk and run the code that person has created.
A person vouches for code by digitally signing it. That signature can be tested for authenticity on your local machine. If the signature is authentic, then you have the option of letting the attached code out of the restrictive sandbox, in part or in full. Much more on the implications of code signing for Java can be found in the article “Sandboxes and Signatures, part 1” and in the book Securing Java. Unfortunately, there are three different, largely incompatible systems for signing Java. So if you want to be able to leave the sandbox at will, you will probably have to support several types of digital signatures. Over the next three weeks, we’ll teach you how to use each system, starting with Netscape’s Object Signing tool.
An important thing to note is that just because an applet is digitally signed, it is not necessarily secure. A digital signature will not prevent an applet from formatting your hard drive if you allow it write access to your system. The user has to make a decision whether or not to trust the person whose certificate generated the digital signature. Keep that fact in mind when you encounter signed code in unfamiliar territory on the Internet.
Getting a certificateGenerally, the steps for getting a certificate will vary based on the vendor, so we won’t cover getting a certificate here. However, if you’re interested, more information on getting a certificate from Verisign can be found in the article “Sandboxes and Signatures, part 2”, which discussed older Netscape signing tools that have since been scrapped.
Exporting and importing certificatesIt is a good idea to export your certificate to a file, just in case you install a new version of Communicator over your old one. Doing so also allows your certificate to follow you to other machines.
To export a certificate, bring up Communicator’s Security Info dialog box by clicking on the padlock icon on the toolbar. Select “Yours” under the “Certificates” heading from the items along the left. Select the certificate you wish to export by clicking on its name. Then, click on the Export button. At this point, you may be asked to enter the password that protects your local browser’s certificate database.
If this is the first time the certificate database has been modified in your browser, you may be prompted to create a password. The certificate database needs a password if other people share your computer. If not, feel free to use a blank password. Next, you will be asked to enter a password to protect the certificate data. This password is used to make sure that no one can steal your certificate if they see an exported copy of it somewhere. Once the certificate password is created and verified, Netscape will prompt you for a filename for storing the certificate. You can copy the certificate file to other machines so you can sign code from there as well.
To import a certificate from a file, which is different than importing a certificate directly from a Certificate Authority, follow the same instructions for exporting, except do not select a certificate from the listing that appears in the “Yours” page. Press the “Import a Certificate” button. If you have not previously entered the password protecting the certificate database of the local copy of Netscape, you will now be prompted for it. After entering the correct password, a file dialog box will come up; use it to select the file containing your certificate.
After selecting the file, you will be prompted for the certificate’s password, which is the password that was entered when you exported the certificate. Assuming all has gone well, you should get a dialog box indicating success.
Netscape Object Signing Tool 1.1The Netscape Object Signing Tool is a command line program that creates digital signatures for files. These signatures aren’t stored in the files themselves, they’re stored in the JAR file in which you bundle your applet. Note that since digital signature information is transmitted in JAR files, you must package your applets in a JAR file in order to sign them, even if they consist of a single class. The syntax for using a JAR file with the HTML APPLET tag is:
Where somefile.class is the class in the JAR file where execution should begin, and jarfile.jar is the URL of the JAR file. The tool is available for most operating systems. While, as of this writing, version 1.0 is still available for download, we recommend that you use version 1.1.
After the download is complete, unpack the archive file in a directory. Included are three files: readme.txt, license.txt, and signtool. To make signing objects easier, put the directory that contains signtool in your PATH environment variable, as per your operating system. For example, a Windows 95 user who unpacked the tool to C:nos would run the following line (and then add it to the autoexec.bat file):
Before attempting to sign anything, check to see if signtool is able to locate the Certificate that will be used to sign objects. UNIX flavors of signtool look for Certificates in the $HOME/.netscape. If your local Netscape files are kept somewhere different, or you are using the Win32 version, signtool must be explicitly told the path to the Certificates. This is done with the -d flag. On Win32, this path is commonly c:Program FilesNetscapeUsersname where name is the name of your Netscape Profile. To verify that your signing Certificate was installed properly run:
or, if your certificate cannot be found,
For example, if your certificates were stored in C:certs, you would type:
If your Certificate still does not appear in the listing, verify that the Certificate is installed in Netscape properly. (See the instructions above). If all else fails, check with Netscape and the issuing Certificate Authority. Make note of the full name of your Certificate, as it appears in the listing. This will be needed when it comes time to sign.
Create a directory in which to put all the class files for the Applet you wish to sign. Once all the class files that make up the Applet are in the right place, the signtool program can create a signed JAR file in one step. Navigate into the directory containing the soon-to-be signed classes. To sign the classes and create a JAR file in one step, issue the command:
If your Communicator Certificate Database is password protected, signtool will prompt for the password before signing the classes. The “.” at the end of the command should be the last thing to appear. It specifies that the signing should begin in the current working directory. The signtool command recursively signs files by default. To keep the tool from recursing through directories, add –norecurse to the command line.
Here’s a brief explanation of the flags used in the previous example, as well as some of the other more useful flags for signing applets:
When the JAR file is created, signtool can be used to test the validity of the signatures. This is done by issuing the command:
Signtool will list the contents of the JAR and verify that they have been signed, and that they have not been tampered with since the signature was created. You may also check to see who signed the JAR file:
signtool -d”<path to certificate>” -w myjar.jar
Adding capabilities to your classesSigning a Java applet does much more than just allow people to verify that you signed it. It can also give your applets the chance to step outside the Java sandbox. If your applet is vouched for by a digital signature, then the applet may request special privileges, such as accessing the file system. However, the user of the applet doesn’t have to let your applet do what you request just because you sign it.
The special privileges an applet can request are called capabilities by Netscape. (Note: Though Netscape and some other vendors use the term “capabilities” to refer to this system, this usage clashes with the use of “capability” as a technical term in the security literature.) Predictably, no two browsers support flexible privileges in quite the same way, so privilege-management code will only work with one browser. (So much for “write once, run anywhere!”) As a result, while Netscape keeps its own internal version of these classes, in order to actually compile and test an applet that can request them, you must download them.
Put the zip file in your CLASSPATH. Now you will be able to develop code that requests extra privileges in Netscape. Note that you should not include these classes with your applet; the Netscape browser running on the remote machine will use its internal version of the classes.
The capabilities library provides a class called PrivilegeManager that handles requests from the program to turn on and off privileges. When the first request to enable a certain privilege is made, PrivilegeManager prompts the browser’s user, showing the certificate used to sign the code requesting the privilege and asking whether the privilege should be granted. If the user agrees to grant the privilege, the privilege is granted for the lifetime of the applet. However, once the applet has obtained a privilege, it can turn the privilege off and on at its discretion.
To request that a particular privilege be enabled, you use the static method enablePrivilege() of class netscape.security.PrivilegeManager. The method takes a single String argument, which is the name of the privilege to enable. Some useful privileges include:
The simplest privilege an applet can request is permission to read System Properties, which include the user’s login name. Here is an example applet which requests privilege to read the user’s name:
A call to enablePrivilege will throw an exception that the applet must catch if the user decides not to grant the privilege specified in the call. Thus, the applet must be prepared to catch instances of netscape.security.ForbiddenTargetException. When a privilege is enabled, it does not have to stay enabled for the entire execution of the applet. There are a couple of ways to turn privileges off (which is always a good idea). First, when the method that calls enablePrivilege returns, the privilege will automatically be disabled. As a result, you should not use a helper method to enable a privilege, because once execution returns from that method, the privilege will no longer be enabled. Second, you can call revertPrivilege, which also takes the name of a privilege as an argument. Finally, you can call disablePrivilege, which turns off a particular privilege. In no case will the granting of the privilege be revoked; the applet can turn the privilege back on by simply calling enablePrivilege again.
Next week, we’ll examine the code signing tools Sun ships in the JDK 1.2.
John Viega is a research associate at Reliable Software Technologies, in Sterling, Va. He holds an M.S. in Computer Science from the University of Virginia. He developed and maintains Mailman, the Gnu mailing list manager. His research interests include software assurance, programming languages, and object-oriented systems.
Tom O’Connor is a software engineer in the research division at Reliable Software Technologies. His interests are computer security and object-oriented software development.
Portions of this article will appear as an appendix in the forthcoming book Securing Java: Getting Down to Business with Mobile Code (John Wiley & Sons, 1998), the second edition of McGraw and Felten’s book, Java Security: Hostile Applets, Holes, & Antidotes.