Package org.ejbca.ui.cli

Source Code of org.ejbca.ui.cli.HSMKeyTool

/*************************************************************************
*                                                                       *
*  EJBCA: The OpenSource Certificate Authority                          *
*                                                                       *
*  This software 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 2.1 of the License, or any later version.                    *
*                                                                       *
*  See terms of license at gnu.org.                                     *
*                                                                       *
*************************************************************************/

package org.ejbca.ui.cli;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.List;

import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.ejbca.util.CMS;
import org.ejbca.util.CliTools;
import org.ejbca.util.keystore.KeyStoreContainer;
import org.ejbca.util.keystore.KeyStoreContainerBase;
import org.ejbca.util.keystore.KeyStoreContainerFactory;



/**
* Manages a key store on a HSM. This class may be extended by a class specific for a typical HSM.
*
* @author primelars
* @version $Id: HSMKeyTool.java 10637 2010-11-22 13:50:58Z primelars $
*
*/
public class HSMKeyTool extends ClientToolBox {
//    private static String CREATE_CA_SWITCH = "createca";
    private static final String ENCRYPT_SWITCH = "encrypt";
    private static final String DECRYPT_SWITCH = "decrypt";
    private static final String VERIFY_SWITCH = "verify";
    private static final String GENERATE_SWITCH = "generate";
    private static final String GENERATE_MODULE_SWITCH = GENERATE_SWITCH+"module";
    private static final String DELETE_SWITCH = "delete";
    private static final String TEST_SWITCH = "test";
    private static final String CREATE_KEYSTORE_SWITCH = "createkeystore";
    private static final String CREATE_KEYSTORE_MODULE_SWITCH = CREATE_KEYSTORE_SWITCH+"module";
    private static final String MOVE_SWITCH = "move";
    private static final String CERT_REQ = "certreq";
    private static final String INSTALL_CERT = "installcert";
    private static final String RENAME = "rename";
    private static final String INSTALL_TRUSTED_ROOT = "installtrusted";
    private static final Object SIGN_SWITCH = "sign";

    final static private Logger log = Logger.getLogger(HSMKeyTool.class);

    /**
     * To be overided if the HSM implementation knows the value of some parameters.
     * @return description of parameters common to all commands.
     */
    String getProviderParameterDescription() {
        return "<signature provider name> <crypto provider name (use null if same as signature)> <keystore provider name>";
    }
    /**
     * @return description of the keystore id.
     */
    String getKeyStoreDescription() {
        return "keystore ID";
    }
    /**
     * The HSM may overide to print an extra comment for the generate command.
     */
    void generateComment(){
        return;
    }
    /**
     * HSMs not capable to create a keystore should overide this method and return false.
     * @return true if the HSM is capable to create a keystore.
     */
    boolean doCreateKeyStore() {
        return true;
    }
    /**
     * HSMs capable of module protection should overide this method and return true.
     * @return true if the HSDM is capable of module protection.
     */
    boolean doModuleProtection() {
        return false;
    }
    /**
     * HSMs capable of module protection should overide this method.
     */
    void setModuleProtection() {
        return;
    }
    private String commandString(String[] sa) {
        String s = "";
        for ( int i=0; i<sa.length; i++) {
            s += sa[i];
            if (i+1<sa.length) {
                s += " ";
            }
        }
        return s;
    }
    private void tooFewArguments(String[] args) {
        log.error("Too few arguments in command: '"+commandString(args)+'\'');
        System.exit(3); // NOPMD, it's not a JEE app
    }
    private boolean doIt(String[] args) throws Exception {
        final String commandStringNoSharedLib = args[0]+" "+args[1]+" ";
        final String commandString = commandStringNoSharedLib+getProviderParameterDescription()+" ";
        /*if ( args[1].toLowerCase().trim().equals(CREATE_CA_SWITCH)) {
            try {
                new HwCaInitCommand(args).execute();
            } catch (Exception e) {
                System.out.println(e.getMessage());           
                //e.printStackTrace();
                System.exit(-1);
            }
            return true;
        } else */
        if ( args[1].toLowerCase().trim().contains(GENERATE_SWITCH) ) {
            if ( args.length < 6 ) {
                System.err.println(commandString + "<all decimal digits RSA key with specified length, otherwise name of ECC curve or DSA key using syntax DSAnnnn> <key entry name> " + '['+'<'+getKeyStoreDescription()+'>'+']');
                generateComment();
                tooFewArguments(args);
            } else {
                if ( args[1].toLowerCase().trim().contains(GENERATE_MODULE_SWITCH) ) {
                    setModuleProtection();
                }
                KeyStoreContainer store = KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args.length>7 ? args[7] : null, null, null);
                String keyEntryName = args.length>6 ? args[6] :"myKey";
                store.generate(args[5], keyEntryName);
                System.err.println("Created certificate with entry "+keyEntryName+'.');
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(DELETE_SWITCH)) {
            if ( args.length < 6 ) {
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " [<key entry name>]");
                tooFewArguments(args);
            } else {
                String alias = args.length>6 ? args[6] : null;
                System.err.println("Deleting certificate with alias "+alias+'.');
                KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).delete(alias);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(CERT_REQ)) {
          // First we check if we have a switch for "-explicitecc" for explicit ecc parameters used in ICAO epassports.
        List<String> argsList = CliTools.getAsModifyableList(args);
        boolean explicitEccParameters = argsList.remove("-explicitecc");
        args = argsList.toArray(new String[0]);
            if ( args.length < 7 ) {
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " <key entry name> [<CN>] -explicitecc");
                tooFewArguments(args);
            } else {
                KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).generateCertReq(args[6], args.length>7 ? args[7] : null, explicitEccParameters);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(INSTALL_CERT)) {
            if ( args.length < 7 ) {
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " <certificate chain in PEM format>");
                tooFewArguments(args);
            } else {
                KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).installCertificate(args[6]);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(INSTALL_TRUSTED_ROOT)) {
            if ( args.length < 7 ) {
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " <trusted root certificate in PEM format>");
                tooFewArguments(args);
            } else {
                KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).installTrustedRoot(args[6]);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(ENCRYPT_SWITCH)) {
            if ( args.length < 7 ) {
                System.err.println("There are two ways of doing the encryption:");
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " <input file> <output file> <key alias>");
                System.err.println(commandStringNoSharedLib + "<input file> <output file> <file with certificate with public key to use>");
                tooFewArguments(args);
            } else if ( args.length < 9 ) {
                Security.addProvider( new BouncyCastleProvider() );
                final X509Certificate cert = (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(new BufferedInputStream(new FileInputStream(args[6])));
                CMS.encrypt(new FileInputStream(args[2]), new FileOutputStream(args[5]), cert);
            } else {
                KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).encrypt(new FileInputStream(args[6]), new FileOutputStream(args[7]), args[8]);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(DECRYPT_SWITCH)) {
            if ( args.length < 9 ) {
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " <input file> <output file> <key alias>");
                tooFewArguments(args);
            } else {
                KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).decrypt(new FileInputStream(args[6]), new FileOutputStream(args[7]), args[8]);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(SIGN_SWITCH)) {
            if ( args.length < 9 ) {
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " <input file> <output file> <key alias>");
                tooFewArguments(args);
            } else {
                KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).sign(new FileInputStream(args[6]), new FileOutputStream(args[7]), args[8]);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(VERIFY_SWITCH)) {
            final CMS.VerifyResult verifyResult;
            if ( args.length < 7 ) {
                System.err.println("There are two ways of doing the encryption:");
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " <input file> <output file> <key alias>");
                System.err.println(commandStringNoSharedLib + "<input file> <output file> <file with certificate with public key to use>");
                tooFewArguments(args);
                return true;
            } else if ( args.length < 9 ) {
                Security.addProvider( new BouncyCastleProvider() );
                final X509Certificate cert = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(new BufferedInputStream(new FileInputStream(args[6])));
                verifyResult = CMS.verify(new FileInputStream(args[2]), new FileOutputStream(args[5]), cert);
            } else {
                verifyResult = KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).verify(new FileInputStream(args[6]), new FileOutputStream(args[7]), args[8]);
            }
            if ( verifyResult==null ) {
                System.out.println("Not possible to parse signed file.");
                System.exit(4); // Not verifying // NOPMD, it's not a JEE app
            }
            System.out.println("The signature of the input " +(verifyResult.isVerifying?"has been":"could not be")+" verified. The file was signed on '"+verifyResult.signDate+"'. The public part of the signing key is in a certificate with serial number "+verifyResult.signerId.getSerialNumber()+" issued by '"+verifyResult.signerId.getIssuer()+"'.");
            if ( !verifyResult.isVerifying ) {
                System.exit(4); // Not verifying // NOPMD, it's not a JEE app
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(TEST_SWITCH)) {
            if ( args.length < 6 ) {
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " [<# of tests or threads>] [<alias for stress test>] [<type of stress test>]");
                tooFewArguments(args);
            } else {
                KeyStoreContainerTest.test(args[2], args[3], args[4], args[5],
                                           args.length>6 ? Integer.parseInt(args[6].trim()) : 1, args.length>7 ? args[7].trim() : null, args.length>8 ? args[8].trim() : null);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(RENAME)) {
            if ( args.length < 8 ) {
                System.err.println(commandString + '<'+getKeyStoreDescription()+'>' + " <old key alias> <new key alias>");
                tooFewArguments(args);
            } else {
                KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], args[5], null, null).renameAlias(args[6], args[7]);
            }
            return true;
        }
        if ( args[1].toLowerCase().trim().equals(MOVE_SWITCH)) {
            if ( args.length < 7 ) {
                System.err.println(commandString + "<from "+getKeyStoreDescription()+"> <to "+getKeyStoreDescription()+'>');
                tooFewArguments(args);
            } else {
                String fromId = args[5];                   
                String toId = args[6];
                System.err.println("Moving entry with alias '"+fromId+"' to alias '"+toId+'.');
                KeyStoreContainerBase.move(args[2], args[3], args[4], fromId, toId, null);
            }
            return true;
        }
        if ( doCreateKeyStore() && args[1].toLowerCase().trim().contains(CREATE_KEYSTORE_SWITCH)) {
            if( args[1].toLowerCase().trim().contains(CREATE_KEYSTORE_MODULE_SWITCH)) {
                setModuleProtection();
            }
            KeyStoreContainerFactory.getInstance(args[4], args[2], args[3], null, null, null).storeKeyStore();
            return true;
        }
        return false;
    }
    /* (non-Javadoc)
     * @see org.ejbca.ui.cli.ClientToolBox#execute(java.lang.String[])
     */
    @Override
  protected void execute(String[] args) {
        try {
            if ( args.length>1 && doIt(args)) {
                return; // command was found.
            }
            PrintWriter pw = new PrintWriter(System.err);
            pw.println("Use one of following commands: ");
//            pw.println("  "+args[0]+" "+CREATE_CA_SWITCH);
            pw.println("  "+args[0]+" "+GENERATE_SWITCH);
            if ( doModuleProtection() ) {
                pw.println("  "+args[0]+" "+GENERATE_MODULE_SWITCH);
            }
            pw.println("  "+args[0]+" "+CERT_REQ);
            pw.println("  "+args[0]+" "+INSTALL_CERT);
            pw.println("  "+args[0]+" "+DELETE_SWITCH);
            pw.println("  "+args[0]+" "+TEST_SWITCH);
            pw.println("  "+args[0]+" "+RENAME);
            if ( doCreateKeyStore() ){
                pw.println("  "+args[0]+" "+CREATE_KEYSTORE_SWITCH);
                if ( doModuleProtection() ) {
                    pw.println("  "+args[0]+" "+CREATE_KEYSTORE_MODULE_SWITCH);
                }
            }
            pw.println("  "+args[0]+" "+ENCRYPT_SWITCH);
            pw.println("  "+args[0]+" "+DECRYPT_SWITCH);
            pw.println("  "+args[0]+" "+SIGN_SWITCH);
            pw.println("  "+args[0]+" "+VERIFY_SWITCH);
            pw.println("  "+args[0]+" "+MOVE_SWITCH);
            pw.flush();
            log.error("Command '"+commandString(args)+"' not found.");
            System.exit(1); // Command not found.  // NOPMD, it's not a JEE app
        } catch (Throwable e) {
            System.err.println("Command could not be executed. See log for stack trace.");
            log.error("Command '"+commandString(args)+"' could not be executed.", e);
            System.exit(2); // Command did not execute OK! // NOPMD, it's not a JEE app
        }
    }
    /* (non-Javadoc)
     * @see org.ejbca.ui.cli.ClientToolBox#getName()
     */
    @Override
    protected String getName() {
        return "HSMKeyTool";
    }
}
TOP

Related Classes of org.ejbca.ui.cli.HSMKeyTool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.