The Artima Developer Community
Sponsored Link

Chapter 3 of Inside the Java Virtual Machine
Security
by Bill Venners

<<  Page 8 of 17  >>

Advertisement

A Code Signing Example

For an example of code signing with the jarsigner tool of the Java 2 SDK 1.2, consider the following types, Doer, Friend, and Stranger. The first type, Doer, defines an interface that the other two types, classes Friend and Stranger implement:

// On CD-ROM in file
// security/ex2/com/artima/security/doer/Doer.java
package com.artima.security.doer;

public interface Doer {

    void doYourThing();
}

Doer declares just one method, doYourThing(). Class Friend and class Stranger implement this method in the exact same way. In fact, besides their names, the two classes are identical:

// On CD-ROM in file
// security/ex2/com/artima/security/friend/Friend.java
package com.artima.security.friend;
import com.artima.security.doer.Doer;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class Friend implements Doer {

    private Doer next;
    private boolean direct;

    public Friend(Doer next, boolean direct) {
        this.next = next;
        this.direct = direct;
    }

    public void doYourThing() {

        if (direct) {

            next.doYourThing();
        }
        else {
            AccessController.doPrivileged(
                new PrivilegedAction() {
                    public Object run() {
                        next.doYourThing();
                        return null;
                    }
                }
            );
        }
    }
}

// On CD-ROM in file
// security/ex2/com/artima/security/stranger/Stranger.java
package com.artima.security.stranger;
import com.artima.security.doer.Doer;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class Stranger implements Doer {

    private Doer next;
    private boolean direct;

    public Stranger(Doer next, boolean direct) {
        this.next = next;
        this.direct = direct;
    }

    public void doYourThing() {

        if (direct) {

            next.doYourThing();
        }
        else {
            AccessController.doPrivileged(
                new PrivilegedAction() {
                    public Object run() {
                        next.doYourThing();
                        return null;
                    }
                }
            );
        }
    }
}

These types -- Doer, Friend, and Stranger -- are designed to illustrate the stack inspection mechanism of the access controller. The motivation behind their design will be made clear later in this chapter, when several examples of stack inspection are given. At this point, however, the class files generated by compiling Friend and Stranger must be signed to prepare them for the upcoming stack inspection examples. The class files generated from Friend.java will be signed by a party referred to fondly as "friend." The class files generated from Stranger.java will be signed by a party referred to somewhat suspiciously as "stranger." The class file generated by Doer will not be signed.

To prepare the class files for signing, they must first be placed into JAR files. Because the class files for Friend and Stranger need to be signed by two different parties, they will be collected into two different JAR files. The two class files generated by compiling Friend.java, Friend.class and Friend$1.class, will be placed into a JAR file called friend.jar. Similarly, the two class files generated by compiling Stranger.java, Stranger.class and Stranger$1.class, will be placed into a JAR file called stranger.jar. (Note that although all of the files in these examples are in the security/ex2 directory of the CD-ROM, to repeat any of the commands that generate files, you'll have to copy the entire security/ex2 directory hierarchy to a writable media, such as a hard disk. But you probably knew that already.)

Friend.java's class files are dropped by the javac compiler in the security/ex2/com/artima/security/friend directory. Because class Friend is declared in the com.artima.security.friend package, Friend.java's class files must be placed in the JAR file in the com/artima/security/friend directory. The following command, executed in the security/ex2 directory, will place Friend.class and Friend$1.class into a newly created JAR file called friend.jar, which is placed in the current directory, security/ex2:

jar cvf friend.jar com/artima/security/friend/*.class

Once the previous command completes, the class files for Friend.java must be removed so they won't be found by the Java virtual machine when it runs the access control examples:

rm com/artima/security/friend/Friend.class
rm com/artima/security/friend/Friend$1.class

Filling a JAR file with Stranger.java's class files, which are dropped by javac in the security/ex2/com/artima/security/stranger directory, requires a similar process. From the security/ex2 directory, the following command must be executed:

jar cvf stranger.jar com/artima/security/stranger/*.class
rm com/artima/security/stranger/Stranger.class
rm com/artima/security/stranger/Stranger$1.class

To sign a JAR file with the jarsigner tool from the Java 2 SDK 1.2, a public/private key pair for the signer must already exist in a keystore file, which is a file for storing named, password-protected keys. The keytool program of the Java 2 SDK 1.2, can be used to generate a new key pair, associate the key pair with a name or alias, and protect it with a password. The alias, which is unique within each keystore file, is used to identify a particular key pair in a particular keystore file. The password for a key pair is required to access or change the information contained in the keystore file for that key pair.

The access control examples expect a keystore file named ivjmkeys in the security/ex2 directory containing key pairs for the aliases "friend" and "stranger." The following command, executed from the security/ex2 directory, will generate the key pair for the alias, friend, with the password, friend4life. In the process, it will create the keystore file named ijvmkeys:

keytool -genkey -alias friend -keypass friend4life -validity 10000 -
keystore ijvmkeys

The -validity 10000 command line argument of the previous keytool command indicates that the key pair should be valid for 10000 days, which at over 27 years, is likely enough time to outlive the product lifecycle of this edition of this book. When the command runs, it will prompt for a keystore password, which is a general password required for any kind of access or change of the keystore file. The keystore password given to ijvmkeys is "ijvm2ed".

The key pair for stranger can be generated with a similar command:

keytool -genkey -alias stranger -keypass stranger4life -validity 10000 -
keystore ijvmkeys

Now that the keystore file ijvmkeys contains key pairs for friend and stranger, and the JAR files friend.jar and stranger.jar contain the appropriate class files, the JAR files can finally be signed. The following jarsigner command, executed from the examples/ex2 directory, will sign the class files contained in friend.jar using friend's private key:

jarsigner -keystore ijvmkeys -storepass ijvm2ed -keypass friend4life
friend.jar friend

A similar command will sign the class files contained in stranger.jar with stranger's private key:

jarsigner -keystore ijvmkeys -storepass ijvm2ed -keypass stranger4life
stranger.jar stranger

Whew, that was a lot of work just to sign two JAR files. And keep in mind that in the real world, you'd have to make sure no one with bad intent got a hold of your private keys, and that you kept track of them. That means not losing the keystore file, remembering the passwords, and so on. In addition, you'll have to get your public keys to anyone who is going to use your signature to give your code access to their system.

<<  Page 8 of 17  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use