001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package  org.jpos.security.jceadapter;
020
021import org.jpos.core.ConfigurationException;
022import org.jpos.core.SimpleConfiguration;
023import org.jpos.iso.ISOUtil;
024import org.jpos.security.SMException;
025import org.jpos.security.SecureDESKey;
026import org.jpos.util.Logger;
027import org.jpos.util.SimpleLogListener;
028
029import java.io.PrintStream;
030import java.util.Properties;
031
032/**
033 * A simple application for sending critical commands to the JCE Security Module.
034 * The functionalities available from this console, are not available programmatically (via API's),
035 * for security reasons, because most of them involve clear (non encrypted) keys.
036 * Those commands are package protected in the JCE Security Module.
037 * @author Hani Samuel Kirollos
038 * @version $Revision$ $Date$
039 */
040public class Console {
041
042    public Console () {
043    }
044
045    /**
046     * @param args
047     */
048    public static void main (String[] args) {
049        new Console().exec(System.out,System.err,args);
050    }
051
052    public void exec(PrintStream outPS,PrintStream errPS,String[] args)
053    {
054        JCESecurityModule sm = new JCESecurityModule();
055        Logger logger = new Logger();
056        logger.addListener(new SimpleLogListener(outPS));
057        sm.setLogger(logger, "jce-security-module");
058        Properties cfgProps = new Properties();
059        SimpleConfiguration cfg = new SimpleConfiguration(cfgProps);
060        String commandName = null;
061        String[] commandParams = new String[10];                 // 10 is Maximum number of paramters for a command
062        outPS.println("Welcome to JCE Security Module console commander!");
063        if (args.length == 0) {
064            outPS.println("Usage: Console [-options] command [commandparameters...]");
065            outPS.println("\nwhere options include:");
066            outPS.println("    -lmk <filename>");
067            outPS.println("                  to specify the Local Master Keys file");
068            outPS.println("    -rebuildlmk   to rebuild new Local Master Keys");
069            outPS.println("                  WARNING: old Local Master Keys gets overwritten");
070            outPS.println("    -jce <provider classname>");
071            outPS.println("                  to specify a JavaTM Cryptography Extension 1.2.1 provider");
072            outPS.println("\nWhere command include: ");
073            outPS.println("    GC <keyLength>");
074            outPS.println("                  to generate a clear key component.");
075            outPS.println("    FK <keyLength> <keyType> <component1> <component2> <component3>");
076            outPS.println("                  to form a key from three clear components.");
077            outPS.println("                  and returns the key encrypted under LMK");
078            outPS.println("                  Odd parity is be forced before encryption under LMK");
079            outPS.println("    CK <keyLength> <keyType> <KEYunderLMK>");
080            outPS.println("                  to generate a key check value for a key encrypted under LMK.");
081            outPS.println("    IK <keyLength> <keyType> <KEYunderKEK> ");
082            outPS.println("       <kekLength> <kekType> <KEKunderLMK> <KEKcheckValue>");
083            outPS.println("                  to import a key from encryption under KEK (eg. ZMK,TMK) to encryption under LMK");
084            outPS.println("                  Odd parity is be forced before encryption under LMK");
085            outPS.println("    KE <keyLength> <keyType> <KEYunderLMK> <KEYcheckValue> ");
086            outPS.println("       <kekLength> <kekType> <KEKunderLMK> <KEKcheckValue> ");
087            outPS.println("                  to translate (export) a key from encryption under LMK");
088            outPS.println("                  to encryption under KEK (eg. ZMK,TMK)");
089        }
090        else {
091            int argsCounter = 0;
092            for (int j = 0; j < 10; j++) {
093                if (argsCounter < args.length &&
094                        args[argsCounter].toLowerCase().compareTo("-lmk") == 0
095                ) {
096                    argsCounter++;
097                    cfgProps.setProperty("lmk", args[argsCounter++]);
098                }
099                if (argsCounter < args.length &&
100                        args[argsCounter].toLowerCase().compareTo("-jce") == 0
101                ) {
102                    argsCounter++;
103                    cfgProps.setProperty("provider", args[argsCounter++]);
104                }
105                if (argsCounter < args.length &&
106                        args[argsCounter].toLowerCase().compareTo("-rebuildlmk") == 0
107                ) {
108                    argsCounter++;
109                    cfgProps.setProperty("rebuildlmk", "true");
110                }
111            }
112            if (argsCounter < args.length) {
113                commandName = args[argsCounter++];
114                int i = 0;
115                while (argsCounter < args.length) {
116                    commandParams[i++] = args[argsCounter++];
117                }
118            }
119            // Configure JCE Security Module
120            try {
121                sm.setConfiguration(cfg);
122            } catch (ConfigurationException e) {
123                e.printStackTrace(errPS);
124                return;
125            }
126            // Execute Command
127            if (commandName != null) {
128                try {
129                    short keyLength = (short)Integer.parseInt(commandParams[0]);
130                    if (commandName.toUpperCase().compareTo("GC") == 0) {
131                        String clearKeyComponenetHexString = sm.generateClearKeyComponent(keyLength);
132                    }
133                    else if (commandName.toUpperCase().compareTo("FK") == 0) {
134                        SecureDESKey KEYunderLMK = sm.formKEYfromThreeClearComponents(keyLength,
135                                commandParams[1].toUpperCase(), commandParams[2], commandParams[3], commandParams[4]);
136                    }
137                    else if (commandName.toUpperCase().compareTo("CK") == 0) {
138                        byte[] keyCheckValue = sm.generateKeyCheckValue(
139                                new SecureDESKey(keyLength,commandParams[1].toUpperCase(), commandParams[2],""));
140                    }
141                    else if (commandName.toUpperCase().compareTo("IK") == 0) {
142                        SecureDESKey KEKunderLMK = new SecureDESKey((short)Integer.parseInt(commandParams[4]),
143                                commandParams[5].toUpperCase(), commandParams[6], commandParams[7]);
144                        sm.importKey(keyLength, commandParams[1].toUpperCase(),
145                                ISOUtil.hex2byte(commandParams[2]), KEKunderLMK, true);
146                    }
147                    else if (commandName.toUpperCase().compareTo("KE") == 0) {
148                        SecureDESKey KEKunderLMK = new SecureDESKey((short)Integer.parseInt(commandParams[4]),
149                                commandParams[5].toUpperCase(), commandParams[6], commandParams[7]);
150                        SecureDESKey KEYunderLMK = new SecureDESKey(keyLength, commandParams[1].toUpperCase(),
151                                commandParams[2], commandParams[3] );
152                        sm.exportKey(KEYunderLMK, KEKunderLMK);
153                    }
154                    else {
155                        System.err.println("Unknown command: " + commandName);
156                    }
157                } catch (SMException e) {
158                    e.printStackTrace(errPS);
159                } catch (java.lang.NumberFormatException e) {
160                    errPS.println("Invalid KeyLength");
161                }
162            }
163            else {
164                errPS.println("No command specified");
165            }
166        }
167    }
168}
169
170
171