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 */ 040/** Simple command-line console for testing the JCE security module. */ 041public class Console { 042 043 /** Default constructor. */ 044 public Console () { 045 } 046 047 /** 048 * Entry point for the JCE security console. 049 * @param args command-line arguments passed to {@link #exec} 050 */ 051 public static void main (String[] args) { 052 new Console().exec(System.out,System.err,args); 053 } 054 055 /** 056 * Runs the JCE security module console with the given I/O streams. 057 * @param outPS output stream 058 * @param errPS error stream 059 * @param args command-line arguments 060 */ 061 public void exec(PrintStream outPS,PrintStream errPS,String[] args) 062 { 063 JCESecurityModule sm = new JCESecurityModule(); 064 Logger logger = new Logger(); 065 logger.addListener(new SimpleLogListener(outPS)); 066 sm.setLogger(logger, "jce-security-module"); 067 Properties cfgProps = new Properties(); 068 SimpleConfiguration cfg = new SimpleConfiguration(cfgProps); 069 String commandName = null; 070 String[] commandParams = new String[10]; // 10 is Maximum number of paramters for a command 071 outPS.println("Welcome to JCE Security Module console commander!"); 072 if (args.length == 0) { 073 outPS.println("Usage: Console [-options] command [commandparameters...]"); 074 outPS.println("\nwhere options include:"); 075 outPS.println(" -lmk <filename>"); 076 outPS.println(" to specify the Local Master Keys file"); 077 outPS.println(" -rebuildlmk to rebuild new Local Master Keys"); 078 outPS.println(" WARNING: old Local Master Keys gets overwritten"); 079 outPS.println(" -jce <provider classname>"); 080 outPS.println(" to specify a JavaTM Cryptography Extension 1.2.1 provider"); 081 outPS.println("\nWhere command include: "); 082 outPS.println(" GC <keyLength>"); 083 outPS.println(" to generate a clear key component."); 084 outPS.println(" FK <keyLength> <keyType> <component1> <component2> <component3>"); 085 outPS.println(" to form a key from three clear components."); 086 outPS.println(" and returns the key encrypted under LMK"); 087 outPS.println(" Odd parity is be forced before encryption under LMK"); 088 outPS.println(" CK <keyLength> <keyType> <KEYunderLMK>"); 089 outPS.println(" to generate a key check value for a key encrypted under LMK."); 090 outPS.println(" IK <keyLength> <keyType> <KEYunderKEK> "); 091 outPS.println(" <kekLength> <kekType> <KEKunderLMK> <KEKcheckValue>"); 092 outPS.println(" to import a key from encryption under KEK (eg. ZMK,TMK) to encryption under LMK"); 093 outPS.println(" Odd parity is be forced before encryption under LMK"); 094 outPS.println(" KE <keyLength> <keyType> <KEYunderLMK> <KEYcheckValue> "); 095 outPS.println(" <kekLength> <kekType> <KEKunderLMK> <KEKcheckValue> "); 096 outPS.println(" to translate (export) a key from encryption under LMK"); 097 outPS.println(" to encryption under KEK (eg. ZMK,TMK)"); 098 } 099 else { 100 int argsCounter = 0; 101 for (int j = 0; j < 10; j++) { 102 if (argsCounter < args.length && 103 args[argsCounter].toLowerCase().compareTo("-lmk") == 0 104 ) { 105 argsCounter++; 106 cfgProps.setProperty("lmk", args[argsCounter++]); 107 } 108 if (argsCounter < args.length && 109 args[argsCounter].toLowerCase().compareTo("-jce") == 0 110 ) { 111 argsCounter++; 112 cfgProps.setProperty("provider", args[argsCounter++]); 113 } 114 if (argsCounter < args.length && 115 args[argsCounter].toLowerCase().compareTo("-rebuildlmk") == 0 116 ) { 117 argsCounter++; 118 cfgProps.setProperty("rebuildlmk", "true"); 119 } 120 } 121 if (argsCounter < args.length) { 122 commandName = args[argsCounter++]; 123 int i = 0; 124 while (argsCounter < args.length) { 125 commandParams[i++] = args[argsCounter++]; 126 } 127 } 128 // Configure JCE Security Module 129 try { 130 sm.setConfiguration(cfg); 131 } catch (ConfigurationException e) { 132 e.printStackTrace(errPS); 133 return; 134 } 135 // Execute Command 136 if (commandName != null) { 137 try { 138 short keyLength = (short)Integer.parseInt(commandParams[0]); 139 if (commandName.toUpperCase().compareTo("GC") == 0) { 140 String clearKeyComponenetHexString = sm.generateClearKeyComponent(keyLength); 141 } 142 else if (commandName.toUpperCase().compareTo("FK") == 0) { 143 SecureDESKey KEYunderLMK = sm.formKEYfromThreeClearComponents(keyLength, 144 commandParams[1].toUpperCase(), commandParams[2], commandParams[3], commandParams[4]); 145 } 146 else if (commandName.toUpperCase().compareTo("CK") == 0) { 147 byte[] keyCheckValue = sm.generateKeyCheckValue( 148 new SecureDESKey(keyLength,commandParams[1].toUpperCase(), commandParams[2],"")); 149 } 150 else if (commandName.toUpperCase().compareTo("IK") == 0) { 151 SecureDESKey KEKunderLMK = new SecureDESKey((short)Integer.parseInt(commandParams[4]), 152 commandParams[5].toUpperCase(), commandParams[6], commandParams[7]); 153 sm.importKey(keyLength, commandParams[1].toUpperCase(), 154 ISOUtil.hex2byte(commandParams[2]), KEKunderLMK, true); 155 } 156 else if (commandName.toUpperCase().compareTo("KE") == 0) { 157 SecureDESKey KEKunderLMK = new SecureDESKey((short)Integer.parseInt(commandParams[4]), 158 commandParams[5].toUpperCase(), commandParams[6], commandParams[7]); 159 SecureDESKey KEYunderLMK = new SecureDESKey(keyLength, commandParams[1].toUpperCase(), 160 commandParams[2], commandParams[3] ); 161 sm.exportKey(KEYunderLMK, KEKunderLMK); 162 } 163 else { 164 System.err.println("Unknown command: " + commandName); 165 } 166 } catch (SMException e) { 167 e.printStackTrace(errPS); 168 } catch (java.lang.NumberFormatException e) { 169 errPS.println("Invalid KeyLength"); 170 } 171 } 172 else { 173 errPS.println("No command specified"); 174 } 175 } 176 } 177} 178 179 180