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.ByteArrayInputStream; 048 import java.io.InputStreamReader; 049 import java.io.PrintWriter; 050 import java.security.cert.Certificate; 051 import java.security.cert.CertificateFactory; 052 053 import iaik.pkcs.pkcs11.DefaultInitializeArgs; 054 import iaik.pkcs.pkcs11.Info; 055 import iaik.pkcs.pkcs11.Module; 056 import iaik.pkcs.pkcs11.Session; 057 import iaik.pkcs.pkcs11.SessionInfo; 058 import iaik.pkcs.pkcs11.Slot; 059 import iaik.pkcs.pkcs11.SlotInfo; 060 import iaik.pkcs.pkcs11.Token; 061 import iaik.pkcs.pkcs11.TokenInfo; 062 import iaik.pkcs.pkcs11.objects.Object; 063 import iaik.pkcs.pkcs11.objects.X509AttributeCertificate; 064 import iaik.pkcs.pkcs11.objects.X509PublicKeyCertificate; 065 066 067 068 /** 069 * This demo program lists information about the objects on a token. 070 * It takes the name of the module 071 * and prompts the user PIN. If the user PIN is not available, 072 * the program will list only public objects but no private objects; i.e. as 073 * defined in PKCS#11 for public read-only sessions. 074 * 075 * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a> 076 * @version 0.1 077 * @invariants 078 */ 079 public class ListObjects { 080 081 static PrintWriter output_; 082 083 static BufferedReader input_; 084 085 static { 086 try { 087 //output_ = new PrintWriter(new FileWriter("GetInfo_output.txt"), true); 088 output_ = new PrintWriter(System.out, true); 089 input_ = new BufferedReader(new InputStreamReader(System.in)); 090 } catch (Throwable thr) { 091 thr.printStackTrace(); 092 output_ = new PrintWriter(System.out, true); 093 input_ = new BufferedReader(new InputStreamReader(System.in)); 094 } 095 } 096 097 public static void main(String[] args) { 098 if ((args.length == 1) || (args.length == 2)) { 099 try { 100 output_.println("################################################################################"); 101 output_.println("load and initialize module: " + args[0]); 102 output_.flush(); 103 Module pkcs11Module = Module.getInstance(args[0]); 104 105 if (args.length == 1) { 106 pkcs11Module.initialize(null); 107 } else { 108 DefaultInitializeArgs arguments = new DefaultInitializeArgs(); 109 byte[] stringBytes = args[1].getBytes(); 110 byte[] reservedBytes = new byte[stringBytes.length + 1]; 111 System.arraycopy(stringBytes, 0, reservedBytes, 0, stringBytes.length); 112 arguments.setReserved(reservedBytes); 113 pkcs11Module.initialize(arguments); 114 } 115 116 Info info = pkcs11Module.getInfo(); 117 output_.println(info); 118 output_.println("################################################################################"); 119 120 121 output_.println("################################################################################"); 122 output_.println("getting list of all slots"); 123 Slot[] slots = pkcs11Module.getSlotList(Module.SlotRequirement.ALL_SLOTS); 124 125 for (int i = 0; i < slots.length; i++) { 126 output_.println("________________________________________________________________________________"); 127 SlotInfo slotInfo = slots[i].getSlotInfo(); 128 output_.print("Slot with ID: "); 129 output_.println(slots[i].getSlotID()); 130 output_.println("--------------------------------------------------------------------------------"); 131 output_.println(slotInfo); 132 output_.println("________________________________________________________________________________"); 133 } 134 output_.println("################################################################################"); 135 136 137 output_.println("################################################################################"); 138 output_.println("getting list of all tokens"); 139 Slot[] slotsWithToken = pkcs11Module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT); 140 Token[] tokens = new Token[slotsWithToken.length]; 141 142 for (int i = 0; i < slotsWithToken.length; i++) { 143 output_.println("________________________________________________________________________________"); 144 tokens[i] = slotsWithToken[i].getToken(); 145 TokenInfo tokenInfo = tokens[i].getTokenInfo(); 146 output_.print("Token in slot with ID: "); 147 output_.println(tokens[i].getSlot().getSlotID()); 148 output_.println("--------------------------------------------------------------------------------"); 149 output_.println(tokenInfo); 150 } 151 output_.println("################################################################################"); 152 153 output_.println("################################################################################"); 154 output_.println("listing objects on tokens"); 155 for (int i = 0; i < tokens.length; i++) { 156 output_.println("________________________________________________________________________________"); 157 output_.println("listing objects for token: "); 158 TokenInfo tokenInfo = tokens[i].getTokenInfo(); 159 output_.println(tokenInfo); 160 Session session = tokens[i] 161 .openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RO_SESSION, null, null); 162 163 if (tokenInfo.isLoginRequired()) { 164 if (tokenInfo.isProtectedAuthenticationPath()) { 165 session.login(Session.UserType.USER, null); // the token prompts the PIN by other means; e.g. PIN-pad 166 } else { 167 output_.print("Enter user-PIN or press [return] to list just public objects: "); 168 output_.flush(); 169 String userPINString = input_.readLine(); 170 output_.println(); 171 output_.print("listing all" + ((userPINString.length() > 0) ? "" : " public") + " objects on token"); 172 if (userPINString.length() > 0) { 173 // login user 174 session.login(Session.UserType.USER, userPINString.toCharArray()); 175 } 176 } 177 } 178 SessionInfo sessionInfo = session.getSessionInfo(); 179 output_.println(" using session:"); 180 output_.println(sessionInfo); 181 182 session.findObjectsInit(null); 183 Object[] objects = session.findObjects(1); 184 185 CertificateFactory x509CertificateFactory = null; 186 while (objects.length > 0) { 187 Object object = objects[0]; 188 output_.println("--------------------------------------------------------------------------------"); 189 output_.println("Object with handle: " + objects[0].getObjectHandle()); 190 output_.println(object); 191 if (object instanceof X509PublicKeyCertificate) { 192 try { 193 byte[] encodedCertificate = ((X509PublicKeyCertificate) object).getValue().getByteArrayValue(); 194 if (x509CertificateFactory == null) { 195 x509CertificateFactory = CertificateFactory.getInstance("X.509"); 196 } 197 Certificate certificate = 198 x509CertificateFactory.generateCertificate(new ByteArrayInputStream(encodedCertificate)); 199 output_.println("................................................................................"); 200 output_.println("The decoded X509PublicKeyCertificate is:"); 201 output_.println(certificate.toString()); 202 output_.println("................................................................................"); 203 } catch (Exception ex) { 204 output_.println("Could not decode this X509PublicKeyCertificate. Exception is: " + ex.toString()); 205 } 206 } else if (object instanceof X509AttributeCertificate) { 207 try { 208 byte[] encodedCertificate = ((X509AttributeCertificate) object).getValue().getByteArrayValue(); 209 if (x509CertificateFactory == null) { 210 x509CertificateFactory = CertificateFactory.getInstance("X.509"); 211 } 212 Certificate certificate = 213 x509CertificateFactory.generateCertificate(new ByteArrayInputStream(encodedCertificate)); 214 output_.println("................................................................................"); 215 output_.println("The decoded X509AttributeCertificate is:"); 216 output_.println(certificate.toString()); 217 output_.println("................................................................................"); 218 } catch (Exception ex) { 219 output_.println("Could not decode this X509AttributeCertificate. Exception is: " + ex.toString()); 220 } 221 } 222 // test the (deep) cloning feature 223 // Object clonedObject = (Object) object.clone(); 224 output_.println("--------------------------------------------------------------------------------"); 225 objects = session.findObjects(1); 226 } 227 session.findObjectsFinal(); 228 229 session.closeSession(); 230 output_.println("________________________________________________________________________________"); 231 } 232 output_.println("################################################################################"); 233 pkcs11Module.finalize(null); 234 } catch (Throwable ex) { 235 ex.printStackTrace(); 236 } 237 } else { 238 printUsage(); 239 } 240 System.gc(); // to finalize and disconnect the pkcs11Module 241 System.exit(0); 242 } 243 244 protected static void printUsage() { 245 output_.println("GetInfo <PKCS#11 module name>"); 246 output_.println("e.g.: GetInfo pk2priv.dll"); 247 } 248 249 }