001 /* Copyright (c) 2002 Graz University of Technology. All rights reserved. 002 * 003 * Redistribution and use in source and binary forms, with or without 004 * modification, are permitted provided that the following conditions are met: 005 * 006 * 1. Redistributions of source code must retain the above copyright notice, 007 * this list of conditions and the following disclaimer. 008 * 009 * 2. Redistributions in binary form must reproduce the above copyright notice, 010 * this list of conditions and the following disclaimer in the documentation 011 * and/or other materials provided with the distribution. 012 * 013 * 3. The end-user documentation included with the redistribution, if any, must 014 * include the following acknowledgment: 015 * 016 * "This product includes software developed by IAIK of Graz University of 017 * Technology." 018 * 019 * Alternately, this acknowledgment may appear in the software itself, if 020 * and wherever such third-party acknowledgments normally appear. 021 * 022 * 4. The names "Graz University of Technology" and "IAIK of Graz University of 023 * Technology" must not be used to endorse or promote products derived from 024 * this software without prior written permission. 025 * 026 * 5. Products derived from this software may not be called 027 * "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior 028 * written permission of Graz University of Technology. 029 * 030 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 031 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 032 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 033 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE 034 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 035 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 036 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 037 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 038 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 039 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 040 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 041 * POSSIBILITY OF SUCH DAMAGE. 042 */ 043 044 package demo.pkcs.pkcs11; 045 046 import java.io.BufferedReader; 047 import java.io.InputStreamReader; 048 import java.io.PrintWriter; 049 import java.util.Hashtable; 050 051 import iaik.pkcs.pkcs11.Info; 052 import iaik.pkcs.pkcs11.Module; 053 import iaik.pkcs.pkcs11.Session; 054 import iaik.pkcs.pkcs11.SessionInfo; 055 import iaik.pkcs.pkcs11.Slot; 056 import iaik.pkcs.pkcs11.State; 057 import iaik.pkcs.pkcs11.Token; 058 import iaik.pkcs.pkcs11.TokenInfo; 059 import iaik.pkcs.pkcs11.objects.Object; 060 061 062 063 /** 064 * This demo program allows to delete certain objects on a certain token. It 065 * allows the user to select a token. Thereafter, it displays the objects on 066 * that token and lets the user select one of them to delete it. 067 * 068 * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a> 069 * @version 0.1 070 * @invariants 071 */ 072 public class DeleteObject { 073 074 static PrintWriter output_; 075 076 static BufferedReader input_; 077 078 static { 079 try { 080 //output_ = new PrintWriter(new FileWriter("GetInfo_output.txt"), true); 081 output_ = new PrintWriter(System.out, true); 082 input_ = new BufferedReader(new InputStreamReader(System.in)); 083 } catch (Throwable thr) { 084 thr.printStackTrace(); 085 output_ = new PrintWriter(System.out, true); 086 input_ = new BufferedReader(new InputStreamReader(System.in)); 087 } 088 } 089 090 public static void main(String[] args) { 091 if (args.length == 1) { 092 try { 093 output_.println("################################################################################"); 094 output_.println("load and initialize module: " + args[0]); 095 Module pkcs11Module = Module.getInstance(args[0]); 096 pkcs11Module.initialize(null); 097 098 Info info = pkcs11Module.getInfo(); 099 output_.println(info); 100 output_.println("################################################################################"); 101 102 103 output_.println("################################################################################"); 104 output_.println("getting list of all tokens"); 105 Slot[] slotsWithToken = pkcs11Module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT); 106 Token[] tokens = new Token[slotsWithToken.length]; 107 Hashtable tokenIDtoToken = new Hashtable(tokens.length); 108 109 for (int i = 0; i < slotsWithToken.length; i++) { 110 output_.println("________________________________________________________________________________"); 111 tokens[i] = slotsWithToken[i].getToken(); 112 TokenInfo tokenInfo = tokens[i].getTokenInfo(); 113 long tokenID = tokens[i].getTokenID(); 114 tokenIDtoToken.put(new Long(tokenID), tokens[i]); 115 output_.println("Token ID: " + tokenID); 116 output_.println(tokenInfo); 117 output_.println("________________________________________________________________________________"); 118 } 119 output_.println("################################################################################"); 120 121 Token selectedToken = null; 122 Long selectedTokenID = null; 123 if (tokens.length == 0) { 124 output_.println("There is no slot with a present token."); 125 System.exit(0); 126 } else if (tokens.length == 1) { 127 output_.println("Taking token with ID: " + tokens[0].getTokenID()); 128 selectedTokenID = new Long(tokens[0].getTokenID()); 129 selectedToken = tokens[0]; 130 } else { 131 boolean gotTokenID = false; 132 while (!gotTokenID) { 133 output_.print("Enter the ID of the token to use or 'x' to exit: "); 134 output_.flush(); 135 String tokenIDstring = input_.readLine(); 136 if (tokenIDstring.equalsIgnoreCase("x")) { 137 System.exit(0); 138 } 139 try { 140 selectedTokenID = new Long(tokenIDstring); 141 selectedToken = (Token) tokenIDtoToken.get(selectedTokenID); 142 if (selectedToken != null) { 143 gotTokenID = true; 144 } else { 145 output_.println("A token with the entered ID \"" + tokenIDstring + "\" does not exist. Try again."); 146 } 147 } catch (NumberFormatException ex) { 148 output_.println("The entered ID \"" + tokenIDstring + "\" is invalid. Try again."); 149 } 150 } 151 } 152 153 output_.println("################################################################################"); 154 Session session = selectedToken 155 .openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RW_SESSION, null, null); 156 157 TokenInfo tokenInfo = selectedToken.getTokenInfo(); 158 if (tokenInfo.isLoginRequired()) { 159 if (tokenInfo.isProtectedAuthenticationPath()) { 160 session.login(Session.UserType.USER, null); // the token prompts the PIN by other means; e.g. PIN-pad 161 } else { 162 output_.print("Enter user-PIN or press [return] to list just public objects: "); 163 output_.flush(); 164 String userPINString = input_.readLine(); 165 output_.println(); 166 output_.print("listing all" + ((userPINString.length() > 0) ? "" : " public") + " objects on token"); 167 if (userPINString.length() > 0) { 168 // login user 169 session.login(Session.UserType.USER, userPINString.toCharArray()); 170 } 171 } 172 } 173 SessionInfo sessionInfo = session.getSessionInfo(); 174 output_.println("using session:"); 175 output_.println(sessionInfo); 176 177 output_.println("listing all" + 178 (((sessionInfo.getState() == State.RO_USER_FUNCTIONS) || (sessionInfo.getState() == State.RW_SO_FUNCTIONS)) 179 ? "" 180 : " public") 181 + " objects on token with ID " + selectedTokenID); 182 output_.println("________________________________________________________________________________"); 183 184 deleteLoop: 185 while (true) { 186 session.findObjectsInit(null); 187 Object[] objects = session.findObjects(1); 188 Hashtable objectHandleToObject = new Hashtable(10); 189 190 while (objects.length > 0) { 191 output_.println("--------------------------------------------------------------------------------"); 192 long objectHandle = objects[0].getObjectHandle(); 193 objectHandleToObject.put(new Long(objectHandle), objects[0]); 194 output_.println("Object with handle: " + objectHandle); 195 output_.println(objects[0]); 196 output_.println("--------------------------------------------------------------------------------"); 197 objects = session.findObjects(1); 198 } 199 session.findObjectsFinal(); 200 201 output_.println("________________________________________________________________________________"); 202 output_.println("################################################################################"); 203 204 Object selectedObject = null; 205 Long selectedObjectHandle; 206 if (objectHandleToObject.isEmpty()) { 207 output_.println("There are no objects on the token."); 208 break deleteLoop; 209 } else { 210 boolean gotObjectHandle = false; 211 while (!gotObjectHandle) { 212 output_.print("Enter the handle of the object to delete or 'x' to exit: "); 213 output_.flush(); 214 String objectHandleString = input_.readLine(); 215 if (objectHandleString.equalsIgnoreCase("x")) { 216 break deleteLoop; 217 } 218 try { 219 selectedObjectHandle = new Long(objectHandleString); 220 selectedObject = (Object) objectHandleToObject.get(selectedObjectHandle); 221 if (selectedObject != null) { 222 gotObjectHandle = true; 223 } else { 224 output_.println("An object with the handle \"" + objectHandleString + "\" does not exist. Try again."); 225 } 226 } catch (NumberFormatException ex) { 227 output_.println("The entered handle \"" + objectHandleString + "\" is invalid. Try again."); 228 } 229 } 230 } 231 232 output_.println("Going to delete this object: "); 233 output_.println(selectedObject); 234 output_.println(); 235 output_.print("Are you sure that you want to DELETE this object permanently? [yes/no] "); 236 output_.flush(); 237 String answer = input_.readLine(); 238 if (answer.equalsIgnoreCase("yes")) { 239 session.destroyObject(selectedObject); 240 output_.println("Object deleted."); 241 } 242 } 243 244 session.closeSession(); 245 pkcs11Module.finalize(null); 246 247 } catch (Throwable ex) { 248 ex.printStackTrace(); 249 } 250 } else { 251 printUsage(); 252 } 253 System.gc(); // to finalize and disconnect the pkcs11Module 254 } 255 256 protected static void printUsage() { 257 output_.println("DeleteObject <PKCS#11 module name>"); 258 output_.println("e.g.: DeleteObject pk2priv.dll"); 259 } 260 261 }