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.security.SecureRandom; 050 import java.util.Arrays; 051 import java.util.List; 052 053 import iaik.pkcs.pkcs11.Mechanism; 054 import iaik.pkcs.pkcs11.Module; 055 import iaik.pkcs.pkcs11.Session; 056 import iaik.pkcs.pkcs11.Slot; 057 import iaik.pkcs.pkcs11.Token; 058 import iaik.pkcs.pkcs11.TokenInfo; 059 import iaik.pkcs.pkcs11.objects.GenericSecretKey; 060 import iaik.pkcs.pkcs11.parameters.SSL3KeyMaterialOutParameters; 061 import iaik.pkcs.pkcs11.parameters.SSL3KeyMaterialParameters; 062 import iaik.pkcs.pkcs11.parameters.SSL3MasterKeyDeriveParameters; 063 import iaik.pkcs.pkcs11.parameters.SSL3RandomDataParameters; 064 import iaik.pkcs.pkcs11.parameters.VersionParameters; 065 066 067 /** 068 * This demo program shows how to use the SSL mechanisms. Ensure that your token 069 * supprots these features. 070 * 071 * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a> 072 * @version 0.1 073 * @invariants 074 */ 075 public class SSLMechanisms { 076 077 static PrintWriter output_; 078 079 static BufferedReader input_; 080 081 static { 082 try { 083 //output_ = new PrintWriter(new FileWriter("GetInfo_output.txt"), true); 084 output_ = new PrintWriter(System.out, true); 085 input_ = new BufferedReader(new InputStreamReader(System.in)); 086 } catch (Throwable thr) { 087 thr.printStackTrace(); 088 output_ = new PrintWriter(System.out, true); 089 input_ = new BufferedReader(new InputStreamReader(System.in)); 090 } 091 } 092 093 public static void main(String[] args) { 094 if ((args.length != 1) && (args.length != 2)) { 095 printUsage(); 096 System.exit(1); 097 } 098 099 try { 100 101 //Security.addProvider(new IAIK()); 102 103 Module pkcs11Module = Module.getInstance(args[0]); 104 pkcs11Module.initialize(null); 105 106 Slot[] slots = pkcs11Module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT); 107 108 if (slots.length == 0) { 109 output_.println("No slot with present token found!"); 110 System.exit(0); 111 } 112 113 Slot selectedSlot = slots[0]; 114 Token token = selectedSlot.getToken(); 115 TokenInfo tokenInfo = token.getTokenInfo(); 116 117 output_.println("################################################################################"); 118 output_.println("Information of Token:"); 119 output_.println(tokenInfo); 120 output_.println("################################################################################"); 121 122 List supportedMechanisms = Arrays.asList(token.getMechanismList()); 123 124 Session session = 125 token.openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RW_SESSION, null, null); 126 127 // if we have to user PIN login user 128 if (args.length == 2) { 129 session.login(Session.UserType.USER, args[1].toCharArray()); 130 } 131 132 GenericSecretKey premasterSecret = null; 133 if (supportedMechanisms.contains(Mechanism.SSL3_PRE_MASTER_KEY_GEN)) { 134 output_.println("################################################################################"); 135 output_.println("Generating premaster secret"); 136 137 VersionParameters versionParameters = new VersionParameters((byte) 3, (byte) 0); 138 139 Mechanism sslPremasterKeyGenerationMechanism = (Mechanism) Mechanism.SSL3_PRE_MASTER_KEY_GEN.clone(); 140 sslPremasterKeyGenerationMechanism.setParameters(versionParameters); 141 142 GenericSecretKey premasterSecretTemplate = new GenericSecretKey(); 143 144 premasterSecret = 145 (GenericSecretKey) session.generateKey(sslPremasterKeyGenerationMechanism, premasterSecretTemplate); 146 147 output_.println("the premaster secret is"); 148 output_.println(premasterSecret.toString()); 149 150 output_.println("################################################################################"); 151 } 152 153 GenericSecretKey masterSecret = null; 154 SecureRandom randomSource = SecureRandom.getInstance("SHA1PRNG"); 155 if (supportedMechanisms.contains(Mechanism.SSL3_MASTER_KEY_DERIVE) && (premasterSecret != null) ) { 156 output_.println("################################################################################"); 157 output_.println("Deriving master secret"); 158 159 byte[] clientRandom = new byte[28]; 160 byte[] serverRandom = new byte[28]; 161 162 output_.print("generating client random... "); 163 output_.flush(); 164 randomSource.nextBytes(clientRandom); 165 output_.println("finished"); 166 output_.print("generating server random... "); 167 output_.flush(); 168 randomSource.nextBytes(serverRandom); 169 output_.println("finished"); 170 171 VersionParameters clientVersion = new VersionParameters(); 172 SSL3RandomDataParameters randomInfo = new SSL3RandomDataParameters(clientRandom, serverRandom); 173 SSL3MasterKeyDeriveParameters masterKeyDeriveParameters = 174 new SSL3MasterKeyDeriveParameters(randomInfo, clientVersion); 175 176 Mechanism sslMasterKeyDerivationMechanism = (Mechanism) Mechanism.SSL3_MASTER_KEY_DERIVE.clone(); 177 sslMasterKeyDerivationMechanism.setParameters(masterKeyDeriveParameters); 178 179 GenericSecretKey masterSecretTemplate = new GenericSecretKey(); 180 181 masterSecret = 182 (GenericSecretKey) session.deriveKey(sslMasterKeyDerivationMechanism, premasterSecret, masterSecretTemplate); 183 184 output_.println("the client version is"); 185 output_.println(masterKeyDeriveParameters.getVersion().toString()); 186 output_.println("the master secret is"); 187 output_.println(masterSecret.toString()); 188 189 output_.println("################################################################################"); 190 } 191 192 if (supportedMechanisms.contains(Mechanism.SSL3_KEY_AND_MAC_DERIVE) && (masterSecret != null) ) { 193 output_.println("################################################################################"); 194 output_.println("Deriving key material"); 195 196 byte[] clientRandom = new byte[28]; 197 byte[] serverRandom = new byte[28]; 198 199 output_.print("generating client random... "); 200 output_.flush(); 201 randomSource.nextBytes(clientRandom); 202 output_.println("finished"); 203 output_.print("generating server random... "); 204 output_.flush(); 205 randomSource.nextBytes(serverRandom); 206 output_.println("finished"); 207 208 VersionParameters clientVersion = new VersionParameters(); 209 SSL3RandomDataParameters randomInfo = new SSL3RandomDataParameters(clientRandom, serverRandom); 210 211 byte[] clientIVBuffer = new byte[16]; 212 byte[] serverIVBuffer = new byte[16]; 213 SSL3KeyMaterialOutParameters returedKeyMaterial = 214 new SSL3KeyMaterialOutParameters(clientIVBuffer, serverIVBuffer); 215 SSL3KeyMaterialParameters keyAndMACDeriveParameters = 216 new SSL3KeyMaterialParameters(80, 128, 128, false, randomInfo, returedKeyMaterial); 217 218 Mechanism sslKeyAndMACDerivationMechanism = (Mechanism) Mechanism.SSL3_KEY_AND_MAC_DERIVE.clone(); 219 sslKeyAndMACDerivationMechanism.setParameters(keyAndMACDeriveParameters); 220 221 session.deriveKey(sslKeyAndMACDerivationMechanism, masterSecret, null); 222 223 output_.println("the key material is"); 224 output_.println(returedKeyMaterial.toString()); 225 226 output_.println("################################################################################"); 227 } 228 229 session.closeSession(); 230 pkcs11Module.finalize(null); 231 232 } catch (Throwable thr) { 233 thr.printStackTrace(); 234 } 235 } 236 237 public static void printUsage() { 238 output_.println("Usage: SSLMechanisms <PKCS#11 module> [<user-PIN>]"); 239 output_.println(" e.g.: SSLMechanisms cryptoki.dll"); 240 output_.println("The given DLL must be in the search path of the system."); 241 } 242 243 }