package org.fnppl.opensdx.security; /* * Copyright (C) 2010-2015 * fine people e.V. <opensdx@fnppl.org> * Henning Thieß <ht@fnppl.org> * * http://fnppl.org */ /* * Software license * * As far as this file or parts of this file is/are software, rather than documentation, this software-license applies / shall be applied. * * This file is part of openSDX * openSDX is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * openSDX is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * and GNU General Public License along with openSDX. * If not, see <http://www.gnu.org/licenses/>. * */ /* * Documentation license * * As far as this file or parts of this file is/are documentation, rather than software, this documentation-license applies / shall be applied. * * This file is part of openSDX. * Permission is granted to copy, distribute and/or modify this document * under the terms of the GNU Free Documentation License, Version 1.3 * or any later version published by the Free Software Foundation; * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. * A copy of the license is included in the section entitled "GNU * Free Documentation License" resp. in the file called "FDL.txt". * */ import java.io.*; import java.util.*; import org.fnppl.opensdx.common.Util; import org.fnppl.opensdx.gui.DefaultConsoleMessageHandler; import org.fnppl.opensdx.gui.MessageHandler; import org.fnppl.opensdx.xml.*; public class SecurityManagerCommandline { private boolean help = false; // --help private String cmd = null; //sign, verify, encrypt, decrpyt private String keystore = null; // --keystore private String keyid = null; // --keyid private String keypw = null; // --keypw private String keypwfile = null;// --keypwfile private String config = null; // --config private String inputName = null;// --in private String outputName = null;// --out private String tsa = null; // --tsa private KeyApprovingStore store = null; private OSDXKey key = null; private SecurityControl sec = null; private MessageHandler mh; public SecurityManagerCommandline() { mh = new DefaultConsoleMessageHandler(); } public void parseArgs(String[] args) { //System.out.println("args: "+Arrays.toString(args)); int i=0; try { while (i<args.length) { String s = args[i]; if (s.startsWith("--")) { if (s.equals("--keystore")) { keystore = args[i+1]; i+=2; } else if (s.equals("--keyid")) { keyid = args[i+1]; i+=2; } else if (s.equals("--keypw")) { keypw = args[i+1]; i+=2; } else if (s.equals("--keypwfile")) { keypwfile = args[i+1]; i+=2; } else if (s.equals("--config")) { config = args[i+1]; i+=2; } else if (s.equals("--in")) { inputName = args[i+1]; i+=2; } else if (s.equals("--out")) { outputName = args[i+1]; i+=2; } else if (s.equals("--tsa")) { tsa = args[i+1]; i+=2; } else if (s.equals("--help")) { help = true; i+=1; } else if (s.startsWith("--")) { System.out.println("CANT UNDERSTAND ARGUMENT: "+s+" "+args[i+1]); i+=2; } } else { cmd = s.toLowerCase(); i+=1; } } if (config!=null) { //read config Element ec = Document.fromFile(new File(config)).getRootElement(); // if (host==null && ec.getChild("host")!=null) host = ec.getChildText("host"); // if (port == -1 && ec.getChild("port")!=null) port = Integer.parseInt(ec.getChildText("port")); // if (prepath==null && ec.getChild("prepath")!=null) prepath = ec.getChildText("prepath"); // if (remotepath==null && ec.getChild("remotepath")!=null) remotepath = ec.getChildText("remotepath"); // if (username==null) { // if (ec.getChild("username")!=null) username = ec.getChildText("username"); // if (ec.getChild("user")!=null) username = ec.getChildText("user"); // } if (keystore==null && ec.getChild("keystore")!=null) keystore = ec.getChildText("keystore"); if (keyid==null && ec.getChild("keyid")!=null) keyid = ec.getChildText("keyid"); if (keypw==null && ec.getChild("keypw")!=null) keypw = ec.getChildText("keypw"); if (keypwfile==null && ec.getChild("keypwfile")!=null) keypwfile = ec.getChildText("keypwfile"); //private key if (ec.getChild("keypair")!=null) { key = OSDXKey.fromElement(ec.getChild("keypair")); } } } catch (Exception ex) { System.out.println("usage: SecurityManagerCommandline --host localhost --port 4221 --prepath \"/\" --user username --keystore defautlKeyStore.xml --keyid 11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:11:22:33:44:55 --keypw key-password [file or list of files to upload]"); System.out.println("usage: SecurityManagerCommandline --config configfile.xml [file or list of files to upload]"); ex.printStackTrace(); } } private void initKey() { try { //init key if (key==null) { if (keystore==null) { error("missing paramenter: key in configfile or keystore"); } if (keyid==null) { error("missing paramenter: key in configfile or keyid"); } store = KeyApprovingStore.fromFile(new File(keystore), mh); key = store.getKey(keyid); if (key==null) error("error: keyid: "+keyid+" not found in given keystore."); } } catch (Exception ex) { error("Error opening keystore from file "+keystore); } try { //unlock key if (keypw!=null) { key.unlockPrivateKey(keypw); } else if (keypwfile!=null) { keypw = Util.loadText(keypwfile); key.unlockPrivateKey(keypw); } else { key.unlockPrivateKey(mh); } if (!key.isPrivateKeyUnlocked()) { error("can not unlock private key"); } } catch (Exception ex) { error("can not unlock private key"); } } private static void error(String msg) { if (msg!=null) System.out.println(msg); System.out.println("use the --help argument to get more information"); System.exit(1); } private void showHelp() { System.out.println("------------------------------------------"); System.out.println("OpenSDX Security Package Command Line Tool"); System.out.println("------------------------------------------"); if (cmd==null || cmd.equals("sign")) { System.out.println("\nCommand SIGN"); System.out.println( "-------------------------"); System.out.println(" Creates a signature for a given file."); System.out.println("\n arguments"); System.out.println(" --keystore FILENAME-KEYSTORE"); System.out.println(" --keyid KEYID-IN-KEYSTORE"); System.out.println(" --keypw PASSWORD"); System.out.println(" --keypwfile FILENAME-PASSWORD"); System.out.println(" --tsa HOSTNAME:PORT: COULD for extra TSA signature, e.g. tsa.fnppl.org:8890"); System.out.println(" --in FILENAME-INPUT"); System.out.println(" --out FILENAME-OUTPUT: default = FILENAME-INPUT_signature.xml"); System.out.println(""); System.out.println(" The key's password can be provided by --keypw OR --keypwfile argument OR you will be asked for it at the console"); System.out.println("\n usage example: SIGN --keystore defautlKeyStore.xml --keyid 11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:11:22:33:44:55 --keypwfile key-password.txt --in example.xml"); } if (cmd==null || cmd.equals("verify")) { System.out.println("\nCommand VERIFY"); System.out.println( "---------------------------"); System.out.println(" Verifies a signature for a given file in the context of a given keystore."); System.out.println("\n arguments"); System.out.println(" --keystore FILENAME-KEYSTORE: a keystore is needed for knowing which keys to trust and knowing the right keyserver settings"); System.out.println(" --in FILENAME-INPUT"); System.out.println(" --out FILENAME-OUTPUT: default = FILENAME-INPUT_verify_report.xml"); System.out.println("\n usage example: VERIFY --keystore defautlKeyStore.xml --in example_signature.xml"); } System.out.println("\n"); } public void process(String[] args) { if (args==null || args.length==0) { showHelp(); System.exit(0); } parseArgs(args); if (help) { showHelp(); return; } if (cmd==null) { error("Error: Missing command"); } else if (cmd.equals("sign")) { sign(); } else if (cmd.equals("verify")) { int ret = verify(); System.exit(ret); } } private void sign() { File fileIn = getFileIn(); initKey(); File fileOut = getFileOut(fileIn, "_signature.xml"); if (outputName == null) { fileOut = new File(fileIn.getAbsolutePath()+"_signature.xml"); } else { fileOut = new File(outputName); } try { System.out.println("Creating signature"); System.out.println("key id : "+key.getKeyID()); System.out.println("input file : "+fileIn.getAbsolutePath()); System.out.println("output file : "+fileOut.getAbsolutePath()); if (tsa==null) { Signature.createSignatureFile(fileIn, fileOut, key); } else { System.out.println("TSA instance: "+tsa); Signature.createSignatureFile(fileIn, fileOut, key, tsa); } System.out.println("Ready."); } catch (Exception e) { //e.printStackTrace(); error("Error: Signature creation failed."); } } public static int justCheckSignature(File keystore, File signature) throws Exception { SecurityControl sec = new SecurityControl(); sec.setMessageHandler(null); KeyApprovingStore store = KeyApprovingStore.fromFile(keystore, null); sec.setKeyStore(store); KeyVerificator kv = KeyVerificator.make(); Vector<OSDXKey> privKeys = store.getAllPrivateSigningKeys(); for (OSDXKey key : privKeys) { kv.addKeyRating(key, TrustRatingOfKey.RATING_ULTIMATE); } sec.setKeyverificator(kv); sec.resetKeyClients();; File fileIn = signature; int ret = 1; //fail Result res = sec.verifyFileSignature(fileIn); if (res.succeeded) { System.out.println("VERIFICATION SUCCEEDED."); ret = 0; } else { System.out.println("VERIFICATION FAILED."); } File fileOut = new File(signature.getParentFile(), signature.getName()+"_verify_report.xml"); try { Document.buildDocument(res.report).writeToFile(fileOut); System.out.println("Report created in "+fileOut.getAbsolutePath()); } catch (Exception e) { System.out.println("Warning: Report creation failed."); //e.printStackTrace(); } return ret; } private int verify() { initSecurityControl(); File fileIn = getFileIn(); int ret = 1; //fail Result res = sec.verifyFileSignature(fileIn); if (res.succeeded) { System.out.println("VERIFICATION SUCCEEDED."); ret = 0; } else { System.out.println("VERIFICATION FAILED."); } File fileOut = getFileOut(fileIn, "_verify_report.xml"); try { Document.buildDocument(res.report).writeToFile(fileOut); System.out.println("Report created in "+fileOut.getAbsolutePath()); } catch (Exception e) { System.out.println("Warning: Report creation failed."); //e.printStackTrace(); } return ret; } private void initSecurityControl() { sec = new SecurityControl(); sec.setMessageHandler(mh); if (keystore==null) { error("Missing parameter: --keystore FILENAME-KEYSTORE"); } try { store = KeyApprovingStore.fromFile(new File(keystore), mh); } catch (Exception ex) { error("Error opening keystore from file "+keystore); } sec.setKeyStore(store); KeyVerificator kv = KeyVerificator.make(); Vector<OSDXKey> privKeys = store.getAllPrivateSigningKeys(); for (OSDXKey key : privKeys) { kv.addKeyRating(key, TrustRatingOfKey.RATING_ULTIMATE); } sec.setKeyverificator(kv); sec.resetKeyClients();; } private File getFileIn() { if (inputName==null) { error("Missing parameter: --in FILENAME"); } File fileIn = new File(inputName); if (!fileIn.exists()) { error("Input file does not exist."); } if (fileIn.isDirectory()) { error("Input file may not be a directory"); } return fileIn; } private File getFileOut(File fileIn, String ext) { File fileOut = null; if (outputName == null) { fileOut = new File(fileIn.getAbsolutePath()+ext); } else { fileOut = new File(outputName); } return fileOut; } public static void main(String[] args) throws Exception { SecurityManagerCommandline cmd = new SecurityManagerCommandline(); cmd.process(args); } }