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 }