[8780cbec] | 1 | package com.nailabs.abac.credential; |
---|
| 2 | |
---|
| 3 | import java.io.*; |
---|
| 4 | import java.util.*; |
---|
| 5 | import java.security.*; |
---|
| 6 | import org.w3c.dom.*; |
---|
| 7 | |
---|
| 8 | import org.apache.xml.security.utils.XMLUtils; |
---|
| 9 | |
---|
| 10 | /** |
---|
| 11 | * Generic command-line processing necessary for signing credentials and |
---|
| 12 | * marking adsd's with hash digests. Portions borrowed from <a href= |
---|
| 13 | * "http://isrl.cs.byu.edu">ISRL</a> researcher, Michael Halcrow. |
---|
| 14 | */ |
---|
| 15 | public class Application { |
---|
| 16 | /** the keystore type is "JKS" by default */ |
---|
| 17 | private static String KEYSTORE = "JKS"; |
---|
| 18 | /** |
---|
| 19 | * the command line arguments are not directly accessible to desecents |
---|
| 20 | * but may be accessed using the <CODE>flagExists()</CODE> and |
---|
| 21 | * <CODE>flagValue()</CODE> methods. |
---|
| 22 | */ |
---|
| 23 | private String argv[] = null; |
---|
| 24 | |
---|
| 25 | // |
---|
| 26 | // Shared application fields |
---|
| 27 | // |
---|
| 28 | /** flag for compiling in the debugging routines */ |
---|
| 29 | protected static boolean DEBUG = true; |
---|
| 30 | /** the application name, which should be supplied by descendents */ |
---|
| 31 | protected String name = "foobar"; |
---|
| 32 | /** parsed XML document in a DOM-structured tree */ |
---|
| 33 | protected Document doc; |
---|
| 34 | protected Element docElement; |
---|
| 35 | /** output stream defaults to standard output */ |
---|
| 36 | protected PrintStream out = System.out; |
---|
| 37 | |
---|
| 38 | // |
---|
| 39 | // Shared commmand line option fields |
---|
| 40 | // |
---|
| 41 | /** the XML input file */ |
---|
| 42 | protected File inXML; |
---|
| 43 | /** the XML output file */ |
---|
| 44 | protected File outXML; |
---|
| 45 | /** the keystore containing key material default instance JKS */ |
---|
| 46 | protected KeyStore keyStore; |
---|
| 47 | /** the file name and path of the serialize keystore */ |
---|
| 48 | protected String keys = null; |
---|
| 49 | /** password for keystore. <EMP>this is a BAD security practice</EMP> */ |
---|
| 50 | protected String password = null; |
---|
| 51 | /** the alias of the signing/verifying key, if any */ |
---|
| 52 | protected String alias = null; |
---|
| 53 | /** include transform information in XML */ |
---|
| 54 | protected boolean includeTransform = false; |
---|
| 55 | /** include certificate in XML signature */ |
---|
| 56 | protected boolean includeCert = true; |
---|
| 57 | /** a boolean for whether to include comments */ |
---|
| 58 | protected boolean noComments = false; |
---|
| 59 | |
---|
| 60 | static { |
---|
| 61 | org.apache.xml.security.Init.init(); |
---|
| 62 | } |
---|
| 63 | |
---|
| 64 | public Application(String argv[]) { |
---|
| 65 | this.argv = argv; |
---|
| 66 | } |
---|
| 67 | |
---|
| 68 | /** |
---|
| 69 | * command line parsing method, which searches for two choices (e.g. |
---|
| 70 | * <pre>flagValue("-h", "--help")</pre>) |
---|
| 71 | * @param firstChoice the command line option search term |
---|
| 72 | * @param secondChoice the command line option search term |
---|
| 73 | * @returns the next string in argument list from specified flag or null |
---|
| 74 | */ |
---|
| 75 | protected String flagValue( String firstChoice, String secondChoice ) { |
---|
| 76 | String toReturn; |
---|
| 77 | if( ( toReturn = flagValue( firstChoice ) ) == null ) |
---|
| 78 | return flagValue( secondChoice ); |
---|
| 79 | else |
---|
| 80 | return toReturn; |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | /** |
---|
| 84 | * search the command line arguments for the specified flag |
---|
| 85 | * @param flag the command line option search term |
---|
| 86 | * @returns the next string in argument list from specified flag or null |
---|
| 87 | */ |
---|
| 88 | protected String flagValue( String flag ) { |
---|
| 89 | for( int x = 0; x < argv.length; x++ ) { |
---|
| 90 | if( argv[x].equals( flag ) ) { |
---|
| 91 | try { |
---|
| 92 | return argv[x+1]; |
---|
| 93 | } catch( Exception e ) { |
---|
| 94 | return null; |
---|
| 95 | } |
---|
| 96 | } |
---|
| 97 | } |
---|
| 98 | return null; |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | /** |
---|
| 102 | * search command line arguments for a boolean argument. |
---|
| 103 | * @param firstChoice usually the single dash and character form |
---|
| 104 | * @param secondChoice usually a GNU double dashed argument |
---|
| 105 | * @returns true if found, false is absent |
---|
| 106 | */ |
---|
| 107 | private boolean flagExists( String firstChoice, String secondChoice ) { |
---|
| 108 | boolean toReturn; |
---|
| 109 | if( flagExists( firstChoice ) ) |
---|
| 110 | return true; |
---|
| 111 | else |
---|
| 112 | return flagExists( secondChoice ); |
---|
| 113 | } |
---|
| 114 | |
---|
| 115 | /** |
---|
| 116 | * search the command line argument for the specified boolean argument. |
---|
| 117 | * @param flag the search term |
---|
| 118 | * @returns true if found, false if not found |
---|
| 119 | */ |
---|
| 120 | private boolean flagExists( String flag ) { |
---|
| 121 | for( int x = 0; x < argv.length; x++ ) { |
---|
| 122 | if( argv[ x ].equals( flag ) ) { |
---|
| 123 | return true; |
---|
| 124 | } |
---|
| 125 | } |
---|
| 126 | return false; |
---|
| 127 | } |
---|
| 128 | |
---|
| 129 | /** convenience method for constructing a file and catching exceptions */ |
---|
| 130 | private File getFile(String path) { |
---|
| 131 | try { |
---|
| 132 | return new File(path); |
---|
| 133 | } catch(Exception ex) { |
---|
| 134 | ex.printStackTrace(); |
---|
| 135 | } |
---|
| 136 | return null; |
---|
| 137 | } |
---|
| 138 | |
---|
| 139 | /** |
---|
| 140 | * a generic parsing method for parsing the command line options. |
---|
| 141 | */ |
---|
| 142 | protected void parseParameters() { |
---|
| 143 | String inName, outName, keystore; |
---|
| 144 | |
---|
| 145 | if( flagExists( "-h", "--help" ) ) { |
---|
| 146 | out.print(name); |
---|
| 147 | out.println(" [options]"); |
---|
| 148 | out.println("Options:"); |
---|
| 149 | out.print("\t-i, --input file"); |
---|
| 150 | out.println("\tInput XML document." ); |
---|
| 151 | out.print("\t-o, --output file"); |
---|
| 152 | out.println("\tOutput XML document." ); |
---|
| 153 | out.print("\t-nc, --no-comments"); |
---|
| 154 | out.println("\tDo not include comments in the digest."); |
---|
| 155 | out.print("\t-nt, --notransform"); |
---|
| 156 | out.println("\tDo not include transform in signature." ); |
---|
| 157 | out.print("\t-c, --includeCert"); |
---|
| 158 | out.println("\tInclude the signing certificate in signature" ); |
---|
| 159 | out.print("\t-i, --input file"); |
---|
| 160 | out.println("\tInput XML document." ); |
---|
| 161 | out.print("\t-k, --keystore file"); |
---|
| 162 | out.println("\tKey store containing the keys to sign/verify" ); |
---|
| 163 | out.print("\t-a, --alias"); |
---|
| 164 | out.println("\t\tthe key store alias of the signator" ); |
---|
| 165 | out.println(); |
---|
| 166 | System.exit(0); |
---|
| 167 | } |
---|
| 168 | // grab the input file |
---|
| 169 | if((inName = flagValue("-i", "--input" )) == null) { |
---|
| 170 | inName = "in.xml"; |
---|
| 171 | } |
---|
| 172 | inXML = getFile(inName); |
---|
| 173 | // grab the output file |
---|
| 174 | if((outName = flagValue("-o", "--output")) == null) { |
---|
| 175 | outName = "out.xml.xml"; |
---|
| 176 | } |
---|
| 177 | outXML = getFile(outName); |
---|
| 178 | // grab the password for the command line, if any |
---|
| 179 | if((password = flagValue("-p","--password")) == null) { |
---|
| 180 | password = "rtml"; |
---|
| 181 | } |
---|
| 182 | // load the keystore |
---|
| 183 | if((keys = flagValue("-k", "--keystore")) == null) { |
---|
| 184 | keys = "keystore.jks"; |
---|
| 185 | } |
---|
| 186 | |
---|
| 187 | // grab the alias from the command line |
---|
| 188 | if((alias = flagValue("-a","--alias")) == null) { |
---|
| 189 | alias = "rtml"; |
---|
| 190 | } |
---|
| 191 | includeCert = (flagExists( "-c", "--include-certs"))? true: false; |
---|
| 192 | noComments = (flagExists( "-nc", "--no-comments"))? true: false; |
---|
| 193 | includeTransform = (flagExists( "-nt", "--no-transform"))? true: false; |
---|
| 194 | } |
---|
| 195 | |
---|
| 196 | /** |
---|
| 197 | * loads the keystore from a file, if specified. This method may be |
---|
| 198 | * overridden in sub-classes. |
---|
| 199 | */ |
---|
| 200 | protected void getKeys() { |
---|
| 201 | if(keys != null) { |
---|
| 202 | try { |
---|
| 203 | if( DEBUG ) { |
---|
| 204 | System.out.println( "Loading keystore from " + keys); |
---|
| 205 | } |
---|
| 206 | FileInputStream fis = new FileInputStream(keys); |
---|
| 207 | keyStore = KeyStore.getInstance("JKS"); |
---|
| 208 | keyStore.load( fis, password.toCharArray() ); |
---|
| 209 | } catch( Exception e ) { |
---|
| 210 | e.printStackTrace(); |
---|
| 211 | keyStore = null; |
---|
| 212 | } |
---|
| 213 | } |
---|
| 214 | } |
---|
| 215 | |
---|
| 216 | /** parse a file into a DOM object */ |
---|
| 217 | protected void readDoc() { |
---|
| 218 | javax.xml.parsers.DocumentBuilderFactory dbf = |
---|
| 219 | javax.xml.parsers.DocumentBuilderFactory.newInstance(); |
---|
| 220 | dbf.setNamespaceAware(true); |
---|
| 221 | try { |
---|
| 222 | javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); |
---|
| 223 | try { |
---|
| 224 | doc = db.parse(inXML); |
---|
| 225 | docElement = doc.getDocumentElement(); |
---|
| 226 | } catch( org.xml.sax.SAXException saxe ) { |
---|
| 227 | saxe.printStackTrace(); |
---|
| 228 | } catch( java.io.IOException ioe ) { |
---|
| 229 | ioe.printStackTrace(); |
---|
| 230 | } |
---|
| 231 | } catch(javax.xml.parsers.ParserConfigurationException pce) { |
---|
| 232 | pce.printStackTrace(); |
---|
| 233 | } |
---|
| 234 | } |
---|
| 235 | |
---|
| 236 | /** write the dom object tree into an XML formatted file */ |
---|
| 237 | protected void writeDoc() { |
---|
| 238 | try { |
---|
| 239 | FileOutputStream fos = new FileOutputStream(outXML); |
---|
| 240 | XMLUtils.outputDOMc14nWithComments(docElement,fos); |
---|
| 241 | fos.close(); |
---|
| 242 | } catch( java.io.FileNotFoundException fnfe ) { |
---|
| 243 | fnfe.printStackTrace(); |
---|
| 244 | } catch( java.io.IOException ioe ) { |
---|
| 245 | ioe.printStackTrace(); |
---|
| 246 | } |
---|
| 247 | } |
---|
| 248 | |
---|
| 249 | } |
---|