FileDocCategorySizeDatePackage
JadTool.javaAPI DocJ2ME MIDP 2.022097Thu Nov 07 12:02:38 GMT 2002com.sun.midp.jadtool

JadTool

public class JadTool extends Object
The JadTool is a commmand line interface to the AppDescriptor class.
see
AppDescriptor
see
SignCert
see
java.security.KeyStore

Fields Summary
private static String
USAGE
Usage text.
private String
command
Holds the command given on the command line.
private String
encoding
Holds the JAD encoding given on the command line.
private String
infile
Holds the input JAD filename given on the command line.
private String
outfile
Holds the output JAD filename given on the command line.
private String
jarfile
Holds the JAR filename given on the command line.
private String
keystore
Holds the keystore filename given on the command line.
private String
alias
Holds the key alias given on the command line.
private String
certnum
Holds the certificate number given on the command line.
private String
chainNum
Holds the certificate chain number given on the command line.
private char[]
storepass
Holds the keystore password given on the command line.
private char[]
keypass
Holds the private key password given on the command line.
private int
certIndex
The converted certificate number.
private int
chainIndex
The converted certificate chain number.
private AppDescriptor
appdesc
The in-memory JAD.
private OutputStream
outstream
Stream to the output JAD.
Constructors Summary
private JadTool()
Keeps this class from being instatiated by the public.


              
       
Methods Summary
private voidcheckCertAndChainNum()
Check the format of the certificate and chain numbers. If there is a problem, print the error, print usage, and exit with -1.

        if (certnum != null) {
            try {
                certIndex = (Integer.valueOf(certnum)).intValue();
                if (certIndex <= 0) {
                    usageError("-certnum must be a positive number");
                }
            } catch (NumberFormatException nfe) {
                usageError("-certnum must be a positive number");
            }
        } 

        if (chainNum != null) {
            try {
                chainIndex = (Integer.valueOf(chainNum)).intValue();
                if (chainIndex <= 0) {
                    usageError("-chainnum must be a positive number");
                }
            } catch (NumberFormatException nfe) {
                usageError("-chainnum must be a positive number");
            }
        }
    
private voiddisplayCert(java.security.cert.X509Certificate c)
Display a certficate.

param
c certificate to display
exception
Exception if there are any errors

        String digest;

        System.out.println();

        System.out.println("Subject: " + c.getSubjectDN().getName());

        System.out.println("Issuer : " + c.getIssuerDN().getName());

        System.out.println("Serial number: " +
                               c.getSerialNumber().toString(16));

        System.out.println("Valid from " + c.getNotBefore() +
                           " to " + c.getNotAfter());
            
        System.out.println("Certificate fingerprints:");

        System.out.print("  MD5: ");
        digest = AppDescriptor.createFingerprint(c.getEncoded(), "MD5");
        System.out.println(digest);

        System.out.print("  SHA: ");
        digest = AppDescriptor.createFingerprint(c.getEncoded(), "SHA");
        System.out.println(digest);

        System.out.println();
    
private voidhelp()
Prints the usage cases of this tool and exits with 0 status.

        usage(0);
    
private voidinitJadUtil()
Initializes an instance of the AppDescriptor class.

If the input file has not been specified, print an error and the usage, then exit with a -1

exception
Exception if there are any errors

        InputStream instream;

        if (infile == null) {
            usageError(command + " requires an input JAD");
        }

        try {
            FileInputStream fis = new FileInputStream(infile);
            instream = new BufferedInputStream(fis);
        } catch (FileNotFoundException fnfe) {
            throw new Exception("Input JAD does not exist: " + infile);
        }

        try {
            appdesc = new AppDescriptor();
            appdesc.load(instream, encoding);
        } catch (UnsupportedEncodingException uee) {
            throw new Exception("Encoding type " + encoding +
                                " not supported");
        } catch (IOException ioe) {
            throw new Exception("Error parsing input JAD: " + infile);
        } finally {
            try {
                // close now so the input and output JAD can be the same.
                instream.close();
            } catch (Exception e) {
                // ignore
            }
        }
    
public static voidmain(java.lang.String[] args)
Performs the command specified in the command line arguments.

Exits with a 0 status if the command was successful. Exits and prints out an error message with a -1 status if the command failed.

Command Summary
---------------

-help - print a usage summary

-addjarsig - add a SHA1withRSA PKCS v1.5 signature of a jarfile to an
app descriptor file.

-addcert - add a https or content provider certificate
to an app descriptor file.

-showcert - show a certificate from the app descriptor
file in human readable form.

Options
-------

These options are valid (and in some cases required to be use) with
the commands above.

-inputjad 

-outputjad 

-encoding 
(default is UTF-8)

-jarfile 

-keystore 
(default is .keystore - same as with keytool)

-storepass 

-alias 

-keypass 

-certnum  (default is "1" or calculated for addcert)

-chainnum  (default is "1")

-all show all certificates


Command Descriptions
--------------------
help: Shows a list of use options.

addcert: Given a certificate and an unsigned jad file
JadTool will create a base64 encoding of the
certificate file and include it in the jad file as

MIDlet-Certificate-1-1: 

"base64 string" is a base64 encoding of the certificate.
If the certificate already exists in the jad file
it will not be duplicated.

showcert: Usage: java JadTool -showcert -certnum 
Allows choice of certificate to view using this command.

addjarsig: Given the alias of a key (stored by the J2SE "keytool"
utility" and an unsigned jad file, the JadTool will
check to see that the jad file contains a
a MIDlet-Certificate-1-1
field. It will then sign the jar file.
In the event that no target jar file is specified
JadTool will hash the jar file located at the URL
specified by the MIDlet-Jar-URL property if no
explicit jar file is given.

param
args command line arguments given by user.

        int exitStatus = -1;

        try {
            new JadTool().run(args);
            exitStatus = 0;
        } catch (Exception e) {
            System.err.println("\n" + e.getMessage() + "\n");
        }

        System.exit(exitStatus);
    
private voidopenKeystoreAndOutputJad()
Open the keystore and output JAD file.

If the key alias or output file has not been specified, print an error and the usage, then exit with a -1

exception
Exception if there are any errors

        File ksfile;
        FileInputStream ksstream;

        if (alias == null) {
            usageError(command + " requires -alias");
        }

        if (outfile == null) {
            usageError(command + " requires an output JAD");
        }

        if (keystore == null) {
            keystore = System.getProperty("user.home") + File.separator
                       + ".keystore";
        }

        try {
            ksfile = new File(keystore);
            // Check if keystore file is empty
            if (ksfile.exists() && ksfile.length() == 0) {
                throw new Exception("Keystore exists, but is empty: " +
                                    keystore);
            }

            ksstream = new FileInputStream(ksfile);
        } catch (FileNotFoundException fnfe) {
            throw new Exception("Keystore does not exist: " + keystore);
        }

        try {
            try {
                // the stream will be closed later
                outstream = new FileOutputStream(outfile);
            } catch (IOException ioe) {
                throw new Exception("Error opening output JAD: " +
                                    outfile);
            }

            try {
                // load the keystore into the AppDescriptor
                appdesc.loadKeyStore(ksstream, storepass);
            } catch (Exception e) {
                throw new Exception("Keystore could not be loaded: " +
                                    e.toString());
            }
        } finally {
            try {
                ksstream.close();
            } catch (IOException e) {
                // ignore
            }
        }
    
private voidperformAddCertCommand(java.lang.String[] args)
Perform the -addcert command, including parsing the line arguments for the -addcert command.

If there is a problem parsing an argument, print the error, print the usage, and exit with a -1.

param
args The command line arguments given to main.
exception
Exception if there are any errors

        int i = 1;

        // change the default for cert number for this command
        certIndex = 0;

        try {
            for (i = 1; i < args.length; i++) {

                if (args[i].equals("-encoding")) {
                    encoding = args[++i];
                } else if (args[i].equals("-keystore")) {
                    keystore = args[++i];
                } else if (args[i].equals("-storepass")) {
                    storepass = args[++i].toCharArray();
                } else if (args[i].equals("-alias")) {
                    alias = args[++i];
                } else if (args[i].equals("-certnum")) {
                    certnum = args[++i];
                } else if (args[i].equals("-chainnum")) {
                    chainNum = args[++i];
                } else if (args[i].equals("-inputjad")) {
                    infile = args[++i];
                } else if (args[i].equals("-outputjad")) {
                    outfile = args[++i];
                } else  {
                    usageError("Illegal option for " + command +
                               ": " + args[i]);
                }
            }
        } catch (ArrayIndexOutOfBoundsException aiobe) {
            usageError("Missing value for " + args[--i]);
        }

        // these methods will check for the presence of the args they need
        checkCertAndChainNum();
        initJadUtil();
        openKeystoreAndOutputJad();

        try {
            appdesc.addCert(alias, chainIndex, certIndex);
            appdesc.store(outstream, encoding);
            return;
        } catch (Exception e) {
            throw new Exception(command + " failed: " + e.toString());
        }
    
private voidperformAddJarSigCommand(java.lang.String[] args)
Perform the -addjarsig command, including parsing the line arguments for the -addjarsig command.

If there is a problem parsing an argument, print the error, print the usage, and exit with a -1.

param
args The command line arguments given to main.
exception
Exception if there are any errors

        int i = 1;

        try {
            for (i = 1; i < args.length; i++) {

                if (args[i].equals("-encoding")) {
                    encoding = args[++i];
                } else if (args[i].equals("-keystore")) {
                    keystore = args[++i];
                } else if (args[i].equals("-storepass")) {
                    storepass = args[++i].toCharArray();
                } else if (args[i].equals("-keypass")) {
                    keypass = args[++i].toCharArray();
                } else if (args[i].equals("-alias")) {
                    alias = args[++i];
                } else if (args[i].equals("-jarfile")) {
                    jarfile = args[++i];
                } else if (args[i].equals("-inputjad")) {
                    infile = args[++i];
                } else if (args[i].equals("-outputjad")) {
                    outfile = args[++i];
                } else {
                    usageError("Illegal option for " + command +
                               ": " + args[i]);
                }
            }
        } catch (ArrayIndexOutOfBoundsException aiobe) {
            usageError("Missing value for " + args[--i]);
        }

        if (keypass == null) {
            usageError(command + " requires -keypass");
        }

        // these methods will check for the presence of the args they need
        initJadUtil();
        openKeystoreAndOutputJad();

        if (jarfile != null) {
            // a jar file was specified for use
            FileInputStream jarinput;

            try {
                jarinput = new FileInputStream(jarfile);
            } catch (FileNotFoundException fnfe) {
                throw new Exception("JAR does not exist: " + jarfile);
            }

            try {
                appdesc.addJarSignature(alias, keypass, jarinput);
            } catch (Exception e) {
                throw new Exception(command + " failed: " + e.toString());
            }

            try {
                jarinput.close();
            } catch (Exception e) {
                // ignore
            }
        } else {
            // Use the JAR at MIDlet-Jar-URL in the JAD
            try {
                appdesc.addJarSignature(alias, keypass);
            } catch (Exception e) {
                throw new Exception(command + " failed: " + e.toString());
            }
        }

        appdesc.store(outstream, encoding);
        return;
    
private voidperformShowCertCommand(java.lang.String[] args)
Perform the -showcert command, including parsing the line arguments for the -showcert command.

If there is a problem parsing an argument, print the error, print the usage, and exit with a -1.

param
args The command line arguments given to main.
exception
Exception if there are any errors

        int i = 1;
        X509Certificate c;
        boolean listAll = false;

        try {
            for (i = 1; i < args.length; i++) {

                if (args[i].equals("-encoding")) {
                    encoding = args[++i];
                } else if (args[i].equals("-certnum")) {
                    certnum = args[++i];
                } else if (args[i].equals("-chainnum")) {
                    chainNum = args[++i];
                } else if (args[i].equals("-all")) {
                    listAll = true;
                } else if (args[i].equals("-inputjad")) {
                    infile = args[++i];
                } else {
                    usageError("Illegal option for " + command +
                               ": " + args[i]);
                }
            }
        } catch (ArrayIndexOutOfBoundsException aiobe) {
            usageError("Missing value for " + args[--i]);
        }

        if (listAll && (chainNum != null || certnum != null)) {
            usageError("-all cannot be used with -certnum or -chainnum");
        }

        // these methods will check for the presence of the args they need
        checkCertAndChainNum();
        initJadUtil();

        if (listAll) {
            Vector certs = appdesc.getAllCerts();

            if (certs.size() == 0) {
                System.out.println("\nNo certificates found in JAD.\n");
                return;
            }

            System.out.println();

            for (i = 0; i < certs.size(); i++) {
                Object[] temp = (Object[])certs.elementAt(i);

                System.out.println((String)temp[AppDescriptor.KEY] + ":");

                displayCert((X509Certificate)temp[AppDescriptor.CERT]);
            }

            return;
        }

        try {
            c = appdesc.getCert(chainIndex, certIndex);
        } catch (Exception e) {
            throw new Exception("-showcert failed: " + e.toString());
        }

        if (c == null) {
            throw new Exception("Certificate " + chainIndex + "-" +
                                certIndex + " not in JAD");
        }

        try {
            displayCert(c);
            return;
        } catch (Exception e) {
            throw new Exception("-showcert failed: " + e.toString());
        }
    
private voidrun(java.lang.String[] args)
Parses the command line arguments and runs the selected command.

Does not return. Exits with a 0 status if the command was successful. Exits and prints out an error message with a -1 status if the command failed.

param
args The command line arguments given to main.
exception
Exception if there are any errors

        if (args.length == 0) {
            usageError("No command given");
        }

        command = args[0];

        try {
            if (command.equals("-addjarsig")) {
                performAddJarSigCommand(args);
                return;
            }

            if (command.equals("-addcert")) {
                performAddCertCommand(args);
                return;
            }

            if (command.equals("-showcert")) {
                performShowCertCommand(args);
                return;
            }

            if (command.equals("-help")) {
                for (int i = 1; i < args.length; i++) {
                    usageError("Illegal option for " + command + ": " +
                               args[i]);
                }

                // help exits
                help();
            }

            usageError("Illegal command: " + command);
        } finally {
            // zero-out passwords
            if (storepass != null) {
                Arrays.fill(storepass, ' ");
                storepass = null;
            }

            if (keypass != null) {
                Arrays.fill(keypass, ' ");
                keypass = null;
            }

            try {
                if (outstream != null) {
                    outstream.close();
                }
            } catch (IOException ioe) {
                // do nothing.  
            }
        }
    
private voidusage(int exitStatus)
Prints the usage cases of this tool and exits.

param
exitStatus status to exit with

        System.out.println(USAGE);
        System.exit(exitStatus);
    
private voidusageError(java.lang.String error)
Prints the usage cases of this tool and exits with -1 status.

param
error usage error message to print

        System.err.println("\n" + error);
        usage(-1);