package com.nailabs.abac.credential; import java.io.*; import java.util.*; import java.security.*; import org.w3c.dom.*; import org.apache.xml.security.utils.XMLUtils; /** * Generic command-line processing necessary for signing credentials and * marking adsd's with hash digests. Portions borrowed from ISRL researcher, Michael Halcrow. */ public class Application { /** the keystore type is "JKS" by default */ private static String KEYSTORE = "JKS"; /** * the command line arguments are not directly accessible to desecents * but may be accessed using the flagExists() and * flagValue() methods. */ private String argv[] = null; // // Shared application fields // /** flag for compiling in the debugging routines */ protected static boolean DEBUG = true; /** the application name, which should be supplied by descendents */ protected String name = "foobar"; /** parsed XML document in a DOM-structured tree */ protected Document doc; protected Element docElement; /** output stream defaults to standard output */ protected PrintStream out = System.out; // // Shared commmand line option fields // /** the XML input file */ protected File inXML; /** the XML output file */ protected File outXML; /** the keystore containing key material default instance JKS */ protected KeyStore keyStore; /** the file name and path of the serialize keystore */ protected String keys = null; /** password for keystore. this is a BAD security practice */ protected String password = null; /** the alias of the signing/verifying key, if any */ protected String alias = null; /** include transform information in XML */ protected boolean includeTransform = false; /** include certificate in XML signature */ protected boolean includeCert = true; /** a boolean for whether to include comments */ protected boolean noComments = false; static { org.apache.xml.security.Init.init(); } public Application(String argv[]) { this.argv = argv; } /** * command line parsing method, which searches for two choices (e.g. *
flagValue("-h", "--help")
) * @param firstChoice the command line option search term * @param secondChoice the command line option search term * @returns the next string in argument list from specified flag or null */ protected String flagValue( String firstChoice, String secondChoice ) { String toReturn; if( ( toReturn = flagValue( firstChoice ) ) == null ) return flagValue( secondChoice ); else return toReturn; } /** * search the command line arguments for the specified flag * @param flag the command line option search term * @returns the next string in argument list from specified flag or null */ protected String flagValue( String flag ) { for( int x = 0; x < argv.length; x++ ) { if( argv[x].equals( flag ) ) { try { return argv[x+1]; } catch( Exception e ) { return null; } } } return null; } /** * search command line arguments for a boolean argument. * @param firstChoice usually the single dash and character form * @param secondChoice usually a GNU double dashed argument * @returns true if found, false is absent */ private boolean flagExists( String firstChoice, String secondChoice ) { boolean toReturn; if( flagExists( firstChoice ) ) return true; else return flagExists( secondChoice ); } /** * search the command line argument for the specified boolean argument. * @param flag the search term * @returns true if found, false if not found */ private boolean flagExists( String flag ) { for( int x = 0; x < argv.length; x++ ) { if( argv[ x ].equals( flag ) ) { return true; } } return false; } /** convenience method for constructing a file and catching exceptions */ private File getFile(String path) { try { return new File(path); } catch(Exception ex) { ex.printStackTrace(); } return null; } /** * a generic parsing method for parsing the command line options. */ protected void parseParameters() { String inName, outName, keystore; if( flagExists( "-h", "--help" ) ) { out.print(name); out.println(" [options]"); out.println("Options:"); out.print("\t-i, --input file"); out.println("\tInput XML document." ); out.print("\t-o, --output file"); out.println("\tOutput XML document." ); out.print("\t-nc, --no-comments"); out.println("\tDo not include comments in the digest."); out.print("\t-nt, --notransform"); out.println("\tDo not include transform in signature." ); out.print("\t-c, --includeCert"); out.println("\tInclude the signing certificate in signature" ); out.print("\t-i, --input file"); out.println("\tInput XML document." ); out.print("\t-k, --keystore file"); out.println("\tKey store containing the keys to sign/verify" ); out.print("\t-a, --alias"); out.println("\t\tthe key store alias of the signator" ); out.println(); System.exit(0); } // grab the input file if((inName = flagValue("-i", "--input" )) == null) { inName = "in.xml"; } inXML = getFile(inName); // grab the output file if((outName = flagValue("-o", "--output")) == null) { outName = "out.xml.xml"; } outXML = getFile(outName); // grab the password for the command line, if any if((password = flagValue("-p","--password")) == null) { password = "rtml"; } // load the keystore if((keys = flagValue("-k", "--keystore")) == null) { keys = "keystore.jks"; } // grab the alias from the command line if((alias = flagValue("-a","--alias")) == null) { alias = "rtml"; } includeCert = (flagExists( "-c", "--include-certs"))? true: false; noComments = (flagExists( "-nc", "--no-comments"))? true: false; includeTransform = (flagExists( "-nt", "--no-transform"))? true: false; } /** * loads the keystore from a file, if specified. This method may be * overridden in sub-classes. */ protected void getKeys() { if(keys != null) { try { if( DEBUG ) { System.out.println( "Loading keystore from " + keys); } FileInputStream fis = new FileInputStream(keys); keyStore = KeyStore.getInstance("JKS"); keyStore.load( fis, password.toCharArray() ); } catch( Exception e ) { e.printStackTrace(); keyStore = null; } } } /** parse a file into a DOM object */ protected void readDoc() { javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); try { javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); try { doc = db.parse(inXML); docElement = doc.getDocumentElement(); } catch( org.xml.sax.SAXException saxe ) { saxe.printStackTrace(); } catch( java.io.IOException ioe ) { ioe.printStackTrace(); } } catch(javax.xml.parsers.ParserConfigurationException pce) { pce.printStackTrace(); } } /** write the dom object tree into an XML formatted file */ protected void writeDoc() { try { FileOutputStream fos = new FileOutputStream(outXML); XMLUtils.outputDOMc14nWithComments(docElement,fos); fos.close(); } catch( java.io.FileNotFoundException fnfe ) { fnfe.printStackTrace(); } catch( java.io.IOException ioe ) { ioe.printStackTrace(); } } }