Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java
38919 views
1
/*
2
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.security.pkcs11;
27
28
import java.io.*;
29
import java.util.*;
30
31
import java.security.*;
32
import java.security.interfaces.*;
33
34
import javax.crypto.interfaces.*;
35
36
import javax.security.auth.Subject;
37
import javax.security.auth.login.LoginException;
38
import javax.security.auth.login.FailedLoginException;
39
import javax.security.auth.callback.Callback;
40
import javax.security.auth.callback.CallbackHandler;
41
import javax.security.auth.callback.ConfirmationCallback;
42
import javax.security.auth.callback.PasswordCallback;
43
import javax.security.auth.callback.TextOutputCallback;
44
45
import sun.security.util.Debug;
46
import sun.security.util.ResourcesMgr;
47
48
import sun.security.pkcs11.Secmod.*;
49
50
import sun.security.pkcs11.wrapper.*;
51
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
52
53
/**
54
* PKCS#11 provider main class.
55
*
56
* @author Andreas Sterbenz
57
* @since 1.5
58
*/
59
public final class SunPKCS11 extends AuthProvider {
60
61
private static final long serialVersionUID = -1354835039035306505L;
62
63
static final Debug debug = Debug.getInstance("sunpkcs11");
64
65
private static int dummyConfigId;
66
67
// the PKCS11 object through which we make the native calls
68
final PKCS11 p11;
69
70
// name of the configuration file
71
private final String configName;
72
73
// configuration information
74
final Config config;
75
76
// id of the PKCS#11 slot we are using
77
final long slotID;
78
79
private CallbackHandler pHandler;
80
private final Object LOCK_HANDLER = new Object();
81
82
final boolean removable;
83
84
final Module nssModule;
85
86
final boolean nssUseSecmodTrust;
87
88
private volatile Token token;
89
90
private TokenPoller poller;
91
92
Token getToken() {
93
return token;
94
}
95
96
public SunPKCS11() {
97
super("SunPKCS11-Dummy", 1.8d, "SunPKCS11-Dummy");
98
throw new ProviderException
99
("SunPKCS11 requires configuration file argument");
100
}
101
102
public SunPKCS11(String configName) {
103
this(checkNull(configName), null);
104
}
105
106
public SunPKCS11(InputStream configStream) {
107
this(getDummyConfigName(), checkNull(configStream));
108
}
109
110
private static <T> T checkNull(T obj) {
111
if (obj == null) {
112
throw new NullPointerException();
113
}
114
return obj;
115
}
116
117
private static synchronized String getDummyConfigName() {
118
int id = ++dummyConfigId;
119
return "---DummyConfig-" + id + "---";
120
}
121
122
/**
123
* @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream)
124
* instead
125
*/
126
@Deprecated
127
public SunPKCS11(String configName, InputStream configStream) {
128
super("SunPKCS11-" +
129
Config.getConfig(configName, configStream).getName(),
130
1.8d, Config.getConfig(configName, configStream).getDescription());
131
this.configName = configName;
132
this.config = Config.removeConfig(configName);
133
134
if (debug != null) {
135
System.out.println("SunPKCS11 loading " + configName);
136
}
137
138
String library = config.getLibrary();
139
String functionList = config.getFunctionList();
140
long slotID = config.getSlotID();
141
int slotListIndex = config.getSlotListIndex();
142
143
boolean useSecmod = config.getNssUseSecmod();
144
boolean nssUseSecmodTrust = config.getNssUseSecmodTrust();
145
Module nssModule = null;
146
147
//
148
// Initialization via Secmod. The way this works is as follows:
149
// SunPKCS11 is either in normal mode or in NSS Secmod mode.
150
// Secmod is activated by specifying one or more of the following
151
// options in the config file:
152
// nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule
153
//
154
// XXX add more explanation here
155
//
156
// If we are in Secmod mode and configured to use either the
157
// nssKeyStore or the nssTrustAnchors module, we automatically
158
// switch to using the NSS trust attributes for trusted certs
159
// (KeyStore).
160
//
161
162
if (useSecmod) {
163
// note: Config ensures library/slot/slotListIndex not specified
164
// in secmod mode.
165
Secmod secmod = Secmod.getInstance();
166
DbMode nssDbMode = config.getNssDbMode();
167
try {
168
String nssLibraryDirectory = config.getNssLibraryDirectory();
169
String nssSecmodDirectory = config.getNssSecmodDirectory();
170
boolean nssOptimizeSpace = config.getNssOptimizeSpace();
171
172
if (secmod.isInitialized()) {
173
if (nssSecmodDirectory != null) {
174
String s = secmod.getConfigDir();
175
if ((s != null) &&
176
(s.equals(nssSecmodDirectory) == false)) {
177
throw new ProviderException("Secmod directory "
178
+ nssSecmodDirectory
179
+ " invalid, NSS already initialized with "
180
+ s);
181
}
182
}
183
if (nssLibraryDirectory != null) {
184
String s = secmod.getLibDir();
185
if ((s != null) &&
186
(s.equals(nssLibraryDirectory) == false)) {
187
throw new ProviderException("NSS library directory "
188
+ nssLibraryDirectory
189
+ " invalid, NSS already initialized with "
190
+ s);
191
}
192
}
193
} else {
194
if (nssDbMode != DbMode.NO_DB) {
195
if (nssSecmodDirectory == null) {
196
throw new ProviderException(
197
"Secmod not initialized and "
198
+ "nssSecmodDirectory not specified");
199
}
200
} else {
201
if (nssSecmodDirectory != null) {
202
throw new ProviderException(
203
"nssSecmodDirectory must not be "
204
+ "specified in noDb mode");
205
}
206
}
207
secmod.initialize(nssDbMode, nssSecmodDirectory,
208
nssLibraryDirectory, nssOptimizeSpace);
209
}
210
} catch (IOException e) {
211
// XXX which exception to throw
212
throw new ProviderException("Could not initialize NSS", e);
213
}
214
List<Module> modules = secmod.getModules();
215
if (config.getShowInfo()) {
216
System.out.println("NSS modules: " + modules);
217
}
218
219
String moduleName = config.getNssModule();
220
if (moduleName == null) {
221
nssModule = secmod.getModule(ModuleType.FIPS);
222
if (nssModule != null) {
223
moduleName = "fips";
224
} else {
225
moduleName = (nssDbMode == DbMode.NO_DB) ?
226
"crypto" : "keystore";
227
}
228
}
229
if (moduleName.equals("fips")) {
230
nssModule = secmod.getModule(ModuleType.FIPS);
231
nssUseSecmodTrust = true;
232
functionList = "FC_GetFunctionList";
233
} else if (moduleName.equals("keystore")) {
234
nssModule = secmod.getModule(ModuleType.KEYSTORE);
235
nssUseSecmodTrust = true;
236
} else if (moduleName.equals("crypto")) {
237
nssModule = secmod.getModule(ModuleType.CRYPTO);
238
} else if (moduleName.equals("trustanchors")) {
239
// XXX should the option be called trustanchor or trustanchors??
240
nssModule = secmod.getModule(ModuleType.TRUSTANCHOR);
241
nssUseSecmodTrust = true;
242
} else if (moduleName.startsWith("external-")) {
243
int moduleIndex;
244
try {
245
moduleIndex = Integer.parseInt
246
(moduleName.substring("external-".length()));
247
} catch (NumberFormatException e) {
248
moduleIndex = -1;
249
}
250
if (moduleIndex < 1) {
251
throw new ProviderException
252
("Invalid external module: " + moduleName);
253
}
254
int k = 0;
255
for (Module module : modules) {
256
if (module.getType() == ModuleType.EXTERNAL) {
257
if (++k == moduleIndex) {
258
nssModule = module;
259
break;
260
}
261
}
262
}
263
if (nssModule == null) {
264
throw new ProviderException("Invalid module " + moduleName
265
+ ": only " + k + " external NSS modules available");
266
}
267
} else {
268
throw new ProviderException(
269
"Unknown NSS module: " + moduleName);
270
}
271
if (nssModule == null) {
272
throw new ProviderException(
273
"NSS module not available: " + moduleName);
274
}
275
if (nssModule.hasInitializedProvider()) {
276
throw new ProviderException("Secmod module already configured");
277
}
278
library = nssModule.libraryName;
279
slotListIndex = nssModule.slot;
280
}
281
this.nssUseSecmodTrust = nssUseSecmodTrust;
282
this.nssModule = nssModule;
283
284
File libraryFile = new File(library);
285
// if the filename is a simple filename without path
286
// (e.g. "libpkcs11.so"), it may refer to a library somewhere on the
287
// OS library search path. Omit the test for file existance as that
288
// only looks in the current directory.
289
if (libraryFile.getName().equals(library) == false) {
290
if (new File(library).isFile() == false) {
291
String msg = "Library " + library + " does not exist";
292
if (config.getHandleStartupErrors() == Config.ERR_HALT) {
293
throw new ProviderException(msg);
294
} else {
295
throw new UnsupportedOperationException(msg);
296
}
297
}
298
}
299
300
try {
301
if (debug != null) {
302
debug.println("Initializing PKCS#11 library " + library);
303
}
304
CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
305
String nssArgs = config.getNssArgs();
306
if (nssArgs != null) {
307
initArgs.pReserved = nssArgs;
308
}
309
// request multithreaded access first
310
initArgs.flags = CKF_OS_LOCKING_OK;
311
PKCS11 tmpPKCS11;
312
try {
313
tmpPKCS11 = PKCS11.getInstance(
314
library, functionList, initArgs,
315
config.getOmitInitialize());
316
} catch (PKCS11Exception e) {
317
if (debug != null) {
318
debug.println("Multi-threaded initialization failed: " + e);
319
}
320
if (config.getAllowSingleThreadedModules() == false) {
321
throw e;
322
}
323
// fall back to single threaded access
324
if (nssArgs == null) {
325
// if possible, use null initArgs for better compatibility
326
initArgs = null;
327
} else {
328
initArgs.flags = 0;
329
}
330
tmpPKCS11 = PKCS11.getInstance(library,
331
functionList, initArgs, config.getOmitInitialize());
332
}
333
p11 = tmpPKCS11;
334
335
CK_INFO p11Info = p11.C_GetInfo();
336
if (p11Info.cryptokiVersion.major < 2) {
337
throw new ProviderException("Only PKCS#11 v2.0 and later "
338
+ "supported, library version is v" + p11Info.cryptokiVersion);
339
}
340
boolean showInfo = config.getShowInfo();
341
if (showInfo) {
342
System.out.println("Information for provider " + getName());
343
System.out.println("Library info:");
344
System.out.println(p11Info);
345
}
346
347
if ((slotID < 0) || showInfo) {
348
long[] slots = p11.C_GetSlotList(false);
349
if (showInfo) {
350
System.out.println("All slots: " + toString(slots));
351
slots = p11.C_GetSlotList(true);
352
System.out.println("Slots with tokens: " + toString(slots));
353
}
354
if (slotID < 0) {
355
if ((slotListIndex < 0)
356
|| (slotListIndex >= slots.length)) {
357
throw new ProviderException("slotListIndex is "
358
+ slotListIndex
359
+ " but token only has " + slots.length + " slots");
360
}
361
slotID = slots[slotListIndex];
362
}
363
}
364
this.slotID = slotID;
365
CK_SLOT_INFO slotInfo = p11.C_GetSlotInfo(slotID);
366
removable = (slotInfo.flags & CKF_REMOVABLE_DEVICE) != 0;
367
initToken(slotInfo);
368
if (nssModule != null) {
369
nssModule.setProvider(this);
370
}
371
} catch (Exception e) {
372
if (config.getHandleStartupErrors() == Config.ERR_IGNORE_ALL) {
373
throw new UnsupportedOperationException
374
("Initialization failed", e);
375
} else {
376
throw new ProviderException
377
("Initialization failed", e);
378
}
379
}
380
}
381
382
private static String toString(long[] longs) {
383
if (longs.length == 0) {
384
return "(none)";
385
}
386
StringBuilder sb = new StringBuilder();
387
sb.append(longs[0]);
388
for (int i = 1; i < longs.length; i++) {
389
sb.append(", ");
390
sb.append(longs[i]);
391
}
392
return sb.toString();
393
}
394
395
public boolean equals(Object obj) {
396
return this == obj;
397
}
398
399
public int hashCode() {
400
return System.identityHashCode(this);
401
}
402
403
private static String[] s(String ...aliases) {
404
return aliases;
405
}
406
407
private static final class Descriptor {
408
final String type;
409
final String algorithm;
410
final String className;
411
final String[] aliases;
412
final int[] mechanisms;
413
414
private Descriptor(String type, String algorithm, String className,
415
String[] aliases, int[] mechanisms) {
416
this.type = type;
417
this.algorithm = algorithm;
418
this.className = className;
419
this.aliases = aliases;
420
this.mechanisms = mechanisms;
421
}
422
private P11Service service(Token token, int mechanism) {
423
return new P11Service
424
(token, type, algorithm, className, aliases, mechanism);
425
}
426
public String toString() {
427
return type + "." + algorithm;
428
}
429
}
430
431
// Map from mechanism to List of Descriptors that should be
432
// registered if the mechanism is supported
433
private final static Map<Integer,List<Descriptor>> descriptors =
434
new HashMap<Integer,List<Descriptor>>();
435
436
private static int[] m(long m1) {
437
return new int[] {(int)m1};
438
}
439
440
private static int[] m(long m1, long m2) {
441
return new int[] {(int)m1, (int)m2};
442
}
443
444
private static int[] m(long m1, long m2, long m3) {
445
return new int[] {(int)m1, (int)m2, (int)m3};
446
}
447
448
private static int[] m(long m1, long m2, long m3, long m4) {
449
return new int[] {(int)m1, (int)m2, (int)m3, (int)m4};
450
}
451
452
private static void d(String type, String algorithm, String className,
453
int[] m) {
454
register(new Descriptor(type, algorithm, className, null, m));
455
}
456
457
private static void d(String type, String algorithm, String className,
458
String[] aliases, int[] m) {
459
register(new Descriptor(type, algorithm, className, aliases, m));
460
}
461
462
private static void register(Descriptor d) {
463
for (int i = 0; i < d.mechanisms.length; i++) {
464
int m = d.mechanisms[i];
465
Integer key = Integer.valueOf(m);
466
List<Descriptor> list = descriptors.get(key);
467
if (list == null) {
468
list = new ArrayList<Descriptor>();
469
descriptors.put(key, list);
470
}
471
list.add(d);
472
}
473
}
474
475
private final static String MD = "MessageDigest";
476
477
private final static String SIG = "Signature";
478
479
private final static String KPG = "KeyPairGenerator";
480
481
private final static String KG = "KeyGenerator";
482
483
private final static String AGP = "AlgorithmParameters";
484
485
private final static String KF = "KeyFactory";
486
487
private final static String SKF = "SecretKeyFactory";
488
489
private final static String CIP = "Cipher";
490
491
private final static String MAC = "Mac";
492
493
private final static String KA = "KeyAgreement";
494
495
private final static String KS = "KeyStore";
496
497
private final static String SR = "SecureRandom";
498
499
static {
500
// names of all the implementation classes
501
// use local variables, only used here
502
String P11Digest = "sun.security.pkcs11.P11Digest";
503
String P11MAC = "sun.security.pkcs11.P11MAC";
504
String P11KeyPairGenerator = "sun.security.pkcs11.P11KeyPairGenerator";
505
String P11KeyGenerator = "sun.security.pkcs11.P11KeyGenerator";
506
String P11RSAKeyFactory = "sun.security.pkcs11.P11RSAKeyFactory";
507
String P11DSAKeyFactory = "sun.security.pkcs11.P11DSAKeyFactory";
508
String P11DHKeyFactory = "sun.security.pkcs11.P11DHKeyFactory";
509
String P11KeyAgreement = "sun.security.pkcs11.P11KeyAgreement";
510
String P11SecretKeyFactory = "sun.security.pkcs11.P11SecretKeyFactory";
511
String P11Cipher = "sun.security.pkcs11.P11Cipher";
512
String P11RSACipher = "sun.security.pkcs11.P11RSACipher";
513
String P11AEADCipher = "sun.security.pkcs11.P11AEADCipher";
514
String P11Signature = "sun.security.pkcs11.P11Signature";
515
String P11PSSSignature = "sun.security.pkcs11.P11PSSSignature";
516
517
// XXX register all aliases
518
519
d(MD, "MD2", P11Digest,
520
m(CKM_MD2));
521
d(MD, "MD5", P11Digest,
522
m(CKM_MD5));
523
d(MD, "SHA1", P11Digest,
524
s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"),
525
m(CKM_SHA_1));
526
527
d(MD, "SHA-224", P11Digest,
528
s("2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4"),
529
m(CKM_SHA224));
530
d(MD, "SHA-256", P11Digest,
531
s("2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"),
532
m(CKM_SHA256));
533
d(MD, "SHA-384", P11Digest,
534
s("2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"),
535
m(CKM_SHA384));
536
d(MD, "SHA-512", P11Digest,
537
s("2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"),
538
m(CKM_SHA512));
539
d(MD, "SHA-512/224", P11Digest,
540
s("2.16.840.1.101.3.4.2.5", "OID.2.16.840.1.101.3.4.2.5"),
541
m(CKM_SHA512_224));
542
d(MD, "SHA-512/256", P11Digest,
543
s("2.16.840.1.101.3.4.2.6", "OID.2.16.840.1.101.3.4.2.6"),
544
m(CKM_SHA512_256));
545
546
d(MAC, "HmacMD5", P11MAC,
547
m(CKM_MD5_HMAC));
548
d(MAC, "HmacSHA1", P11MAC,
549
s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"),
550
m(CKM_SHA_1_HMAC));
551
d(MAC, "HmacSHA224", P11MAC,
552
s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"),
553
m(CKM_SHA224_HMAC));
554
d(MAC, "HmacSHA256", P11MAC,
555
s("1.2.840.113549.2.9", "OID.1.2.840.113549.2.9"),
556
m(CKM_SHA256_HMAC));
557
d(MAC, "HmacSHA384", P11MAC,
558
s("1.2.840.113549.2.10", "OID.1.2.840.113549.2.10"),
559
m(CKM_SHA384_HMAC));
560
d(MAC, "HmacSHA512", P11MAC,
561
s("1.2.840.113549.2.11", "OID.1.2.840.113549.2.11"),
562
m(CKM_SHA512_HMAC));
563
d(MAC, "HmacSHA512/224", P11MAC,
564
s("1.2.840.113549.2.12", "OID.1.2.840.113549.2.12"),
565
m(CKM_SHA512_224_HMAC));
566
d(MAC, "HmacSHA512/256", P11MAC,
567
s("1.2.840.113549.2.13", "OID.1.2.840.113549.2.13"),
568
m(CKM_SHA512_256_HMAC));
569
570
d(MAC, "SslMacMD5", P11MAC,
571
m(CKM_SSL3_MD5_MAC));
572
d(MAC, "SslMacSHA1", P11MAC,
573
m(CKM_SSL3_SHA1_MAC));
574
575
d(KPG, "RSA", P11KeyPairGenerator,
576
s("1.2.840.113549.1.1", "OID.1.2.840.113549.1.1"),
577
m(CKM_RSA_PKCS_KEY_PAIR_GEN));
578
579
d(KPG, "DSA", P11KeyPairGenerator,
580
s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
581
m(CKM_DSA_KEY_PAIR_GEN));
582
d(KPG, "DH", P11KeyPairGenerator, s("DiffieHellman"),
583
m(CKM_DH_PKCS_KEY_PAIR_GEN));
584
d(KPG, "EC", P11KeyPairGenerator,
585
m(CKM_EC_KEY_PAIR_GEN));
586
587
d(KG, "ARCFOUR", P11KeyGenerator, s("RC4"),
588
m(CKM_RC4_KEY_GEN));
589
d(KG, "DES", P11KeyGenerator,
590
m(CKM_DES_KEY_GEN));
591
d(KG, "DESede", P11KeyGenerator,
592
m(CKM_DES3_KEY_GEN, CKM_DES2_KEY_GEN));
593
d(KG, "AES", P11KeyGenerator,
594
m(CKM_AES_KEY_GEN));
595
d(KG, "Blowfish", P11KeyGenerator,
596
m(CKM_BLOWFISH_KEY_GEN));
597
598
// register (Secret)KeyFactories if there are any mechanisms
599
// for a particular algorithm that we support
600
d(KF, "RSA", P11RSAKeyFactory,
601
s("1.2.840.113549.1.1", "OID.1.2.840.113549.1.1"),
602
m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509));
603
d(KF, "DSA", P11DSAKeyFactory,
604
s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
605
m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1));
606
d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"),
607
m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
608
d(KF, "EC", P11DHKeyFactory,
609
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
610
CKM_ECDSA, CKM_ECDSA_SHA1));
611
612
// AlgorithmParameters for EC.
613
// Only needed until we have an EC implementation in the SUN provider.
614
d(AGP, "EC", "sun.security.util.ECParameters",
615
s("1.2.840.10045.2.1"),
616
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
617
CKM_ECDSA, CKM_ECDSA_SHA1));
618
619
d(AGP, "GCM", "sun.security.util.GCMParameters",
620
m(CKM_AES_GCM));
621
622
d(KA, "DH", P11KeyAgreement, s("DiffieHellman"),
623
m(CKM_DH_PKCS_DERIVE));
624
d(KA, "ECDH", "sun.security.pkcs11.P11ECDHKeyAgreement",
625
m(CKM_ECDH1_DERIVE));
626
627
d(SKF, "ARCFOUR", P11SecretKeyFactory, s("RC4"),
628
m(CKM_RC4));
629
d(SKF, "DES", P11SecretKeyFactory,
630
m(CKM_DES_CBC));
631
d(SKF, "DESede", P11SecretKeyFactory,
632
m(CKM_DES3_CBC));
633
d(SKF, "AES", P11SecretKeyFactory,
634
s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"),
635
m(CKM_AES_CBC));
636
d(SKF, "Blowfish", P11SecretKeyFactory,
637
m(CKM_BLOWFISH_CBC));
638
639
// XXX attributes for Ciphers (supported modes, padding)
640
d(CIP, "ARCFOUR", P11Cipher, s("RC4"),
641
m(CKM_RC4));
642
d(CIP, "DES/CBC/NoPadding", P11Cipher,
643
m(CKM_DES_CBC));
644
d(CIP, "DES/CBC/PKCS5Padding", P11Cipher,
645
m(CKM_DES_CBC_PAD, CKM_DES_CBC));
646
d(CIP, "DES/ECB/NoPadding", P11Cipher,
647
m(CKM_DES_ECB));
648
d(CIP, "DES/ECB/PKCS5Padding", P11Cipher, s("DES"),
649
m(CKM_DES_ECB));
650
651
d(CIP, "DESede/CBC/NoPadding", P11Cipher,
652
m(CKM_DES3_CBC));
653
d(CIP, "DESede/CBC/PKCS5Padding", P11Cipher,
654
m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
655
d(CIP, "DESede/ECB/NoPadding", P11Cipher,
656
m(CKM_DES3_ECB));
657
d(CIP, "DESede/ECB/PKCS5Padding", P11Cipher, s("DESede"),
658
m(CKM_DES3_ECB));
659
d(CIP, "AES/CBC/NoPadding", P11Cipher,
660
m(CKM_AES_CBC));
661
d(CIP, "AES_128/CBC/NoPadding", P11Cipher,
662
s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
663
m(CKM_AES_CBC));
664
d(CIP, "AES_192/CBC/NoPadding", P11Cipher,
665
s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
666
m(CKM_AES_CBC));
667
d(CIP, "AES_256/CBC/NoPadding", P11Cipher,
668
s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"),
669
m(CKM_AES_CBC));
670
d(CIP, "AES/CBC/PKCS5Padding", P11Cipher,
671
m(CKM_AES_CBC_PAD, CKM_AES_CBC));
672
d(CIP, "AES/ECB/NoPadding", P11Cipher,
673
m(CKM_AES_ECB));
674
d(CIP, "AES_128/ECB/NoPadding", P11Cipher,
675
s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
676
m(CKM_AES_ECB));
677
d(CIP, "AES_192/ECB/NoPadding", P11Cipher,
678
s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
679
m(CKM_AES_ECB));
680
d(CIP, "AES_256/ECB/NoPadding", P11Cipher,
681
s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"),
682
m(CKM_AES_ECB));
683
d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, s("AES"),
684
m(CKM_AES_ECB));
685
d(CIP, "AES/CTR/NoPadding", P11Cipher,
686
m(CKM_AES_CTR));
687
688
d(CIP, "AES/GCM/NoPadding", P11AEADCipher,
689
m(CKM_AES_GCM));
690
d(CIP, "AES_128/GCM/NoPadding", P11AEADCipher,
691
s("2.16.840.1.101.3.4.1.6", "OID.2.16.840.1.101.3.4.1.6"),
692
m(CKM_AES_GCM));
693
d(CIP, "AES_192/GCM/NoPadding", P11AEADCipher,
694
s("2.16.840.1.101.3.4.1.26", "OID.2.16.840.1.101.3.4.1.26"),
695
m(CKM_AES_GCM));
696
d(CIP, "AES_256/GCM/NoPadding", P11AEADCipher,
697
s("2.16.840.1.101.3.4.1.46", "OID.2.16.840.1.101.3.4.1.46"),
698
m(CKM_AES_GCM));
699
700
d(CIP, "Blowfish/CBC/NoPadding", P11Cipher,
701
m(CKM_BLOWFISH_CBC));
702
d(CIP, "Blowfish/CBC/PKCS5Padding", P11Cipher,
703
m(CKM_BLOWFISH_CBC));
704
705
d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher, s("RSA"),
706
m(CKM_RSA_PKCS));
707
d(CIP, "RSA/ECB/NoPadding", P11RSACipher,
708
m(CKM_RSA_X_509));
709
710
d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"),
711
m(CKM_DSA));
712
d(SIG, "DSA", P11Signature,
713
s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27",
714
"1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"),
715
m(CKM_DSA_SHA1, CKM_DSA));
716
d(SIG, "SHA224withDSA", P11Signature,
717
s("2.16.840.1.101.3.4.3.1", "OID.2.16.840.1.101.3.4.3.1"),
718
m(CKM_DSA_SHA224));
719
d(SIG, "SHA256withDSA", P11Signature,
720
s("2.16.840.1.101.3.4.3.2", "OID.2.16.840.1.101.3.4.3.2"),
721
m(CKM_DSA_SHA256));
722
d(SIG, "SHA384withDSA", P11Signature,
723
s("2.16.840.1.101.3.4.3.3", "OID.2.16.840.1.101.3.4.3.3"),
724
m(CKM_DSA_SHA384));
725
d(SIG, "SHA512withDSA", P11Signature,
726
s("2.16.840.1.101.3.4.3.4", "OID.2.16.840.1.101.3.4.3.4"),
727
m(CKM_DSA_SHA512));
728
729
d(SIG, "NONEwithECDSA", P11Signature,
730
m(CKM_ECDSA));
731
d(SIG, "SHA1withECDSA", P11Signature,
732
s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"),
733
m(CKM_ECDSA_SHA1, CKM_ECDSA));
734
d(SIG, "SHA224withECDSA", P11Signature,
735
s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"),
736
m(CKM_ECDSA));
737
d(SIG, "SHA256withECDSA", P11Signature,
738
s("1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"),
739
m(CKM_ECDSA));
740
d(SIG, "SHA384withECDSA", P11Signature,
741
s("1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"),
742
m(CKM_ECDSA));
743
d(SIG, "SHA512withECDSA", P11Signature,
744
s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
745
m(CKM_ECDSA));
746
d(SIG, "MD2withRSA", P11Signature,
747
s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"),
748
m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
749
d(SIG, "MD5withRSA", P11Signature,
750
s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"),
751
m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
752
d(SIG, "SHA1withRSA", P11Signature,
753
s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
754
"1.3.14.3.2.29"),
755
m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
756
d(SIG, "SHA224withRSA", P11Signature,
757
s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"),
758
m(CKM_SHA224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
759
d(SIG, "SHA256withRSA", P11Signature,
760
s("1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11"),
761
m(CKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
762
d(SIG, "SHA384withRSA", P11Signature,
763
s("1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12"),
764
m(CKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
765
d(SIG, "SHA512withRSA", P11Signature,
766
s("1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13"),
767
m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
768
d(SIG, "RSASSA-PSS", P11PSSSignature,
769
s("1.2.840.113549.1.1.10", "OID.1.2.840.113549.1.1.10"),
770
m(CKM_RSA_PKCS_PSS));
771
d(SIG, "SHA1withRSASSA-PSS", P11PSSSignature,
772
m(CKM_SHA1_RSA_PKCS_PSS));
773
d(SIG, "SHA224withRSASSA-PSS", P11PSSSignature,
774
m(CKM_SHA224_RSA_PKCS_PSS));
775
d(SIG, "SHA256withRSASSA-PSS", P11PSSSignature,
776
m(CKM_SHA256_RSA_PKCS_PSS));
777
d(SIG, "SHA384withRSASSA-PSS", P11PSSSignature,
778
m(CKM_SHA384_RSA_PKCS_PSS));
779
d(SIG, "SHA512withRSASSA-PSS", P11PSSSignature,
780
m(CKM_SHA512_RSA_PKCS_PSS));
781
782
d(KG, "SunTlsRsaPremasterSecret",
783
"sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
784
s("SunTls12RsaPremasterSecret"),
785
m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN));
786
d(KG, "SunTlsMasterSecret",
787
"sun.security.pkcs11.P11TlsMasterSecretGenerator",
788
m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE,
789
CKM_SSL3_MASTER_KEY_DERIVE_DH,
790
CKM_TLS_MASTER_KEY_DERIVE_DH));
791
d(KG, "SunTls12MasterSecret",
792
"sun.security.pkcs11.P11TlsMasterSecretGenerator",
793
m(CKM_TLS12_MASTER_KEY_DERIVE, CKM_TLS12_MASTER_KEY_DERIVE_DH));
794
d(KG, "SunTlsKeyMaterial",
795
"sun.security.pkcs11.P11TlsKeyMaterialGenerator",
796
m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE));
797
d(KG, "SunTls12KeyMaterial",
798
"sun.security.pkcs11.P11TlsKeyMaterialGenerator",
799
m(CKM_TLS12_KEY_AND_MAC_DERIVE));
800
d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator",
801
m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL));
802
d(KG, "SunTls12Prf", "sun.security.pkcs11.P11TlsPrfGenerator",
803
m(CKM_TLS_MAC));
804
}
805
806
// background thread that periodically checks for token insertion
807
// if no token is present. We need to do that in a separate thread because
808
// the insertion check may block for quite a long time on some tokens.
809
private static class TokenPoller implements Runnable {
810
private final SunPKCS11 provider;
811
private volatile boolean enabled;
812
private TokenPoller(SunPKCS11 provider) {
813
this.provider = provider;
814
enabled = true;
815
}
816
public void run() {
817
int interval = provider.config.getInsertionCheckInterval();
818
while (enabled) {
819
try {
820
Thread.sleep(interval);
821
} catch (InterruptedException e) {
822
break;
823
}
824
if (enabled == false) {
825
break;
826
}
827
try {
828
provider.initToken(null);
829
} catch (PKCS11Exception e) {
830
// ignore
831
}
832
}
833
}
834
void disable() {
835
enabled = false;
836
}
837
}
838
839
// create the poller thread, if not already active
840
private void createPoller() {
841
if (poller != null) {
842
return;
843
}
844
TokenPoller poller = new TokenPoller(this);
845
Thread t = new Thread(poller, "Poller " + getName());
846
t.setDaemon(true);
847
t.setPriority(Thread.MIN_PRIORITY);
848
t.start();
849
this.poller = poller;
850
}
851
852
// destroy the poller thread, if active
853
private void destroyPoller() {
854
if (poller != null) {
855
poller.disable();
856
poller = null;
857
}
858
}
859
860
private boolean hasValidToken() {
861
/* Commented out to work with Solaris softtoken impl which
862
returns 0-value flags, e.g. both REMOVABLE_DEVICE and
863
TOKEN_PRESENT are false, when it can't access the token.
864
if (removable == false) {
865
return true;
866
}
867
*/
868
Token token = this.token;
869
return (token != null) && token.isValid();
870
}
871
872
// destroy the token. Called if we detect that it has been removed
873
synchronized void uninitToken(Token token) {
874
if (this.token != token) {
875
// mismatch, our token must already be destroyed
876
return;
877
}
878
destroyPoller();
879
this.token = null;
880
// unregister all algorithms
881
AccessController.doPrivileged(new PrivilegedAction<Object>() {
882
public Object run() {
883
clear();
884
return null;
885
}
886
});
887
createPoller();
888
}
889
890
// test if a token is present and initialize this provider for it if so.
891
// does nothing if no token is found
892
// called from constructor and by poller
893
private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception {
894
if (slotInfo == null) {
895
slotInfo = p11.C_GetSlotInfo(slotID);
896
}
897
if (removable && (slotInfo.flags & CKF_TOKEN_PRESENT) == 0) {
898
createPoller();
899
return;
900
}
901
destroyPoller();
902
boolean showInfo = config.getShowInfo();
903
if (showInfo) {
904
System.out.println("Slot info for slot " + slotID + ":");
905
System.out.println(slotInfo);
906
}
907
final Token token = new Token(this);
908
if (showInfo) {
909
System.out.println
910
("Token info for token in slot " + slotID + ":");
911
System.out.println(token.tokenInfo);
912
}
913
long[] supportedMechanisms = p11.C_GetMechanismList(slotID);
914
915
// Create a map from the various Descriptors to the "most
916
// preferred" mechanism that was defined during the
917
// static initialization. For example, DES/CBC/PKCS5Padding
918
// could be mapped to CKM_DES_CBC_PAD or CKM_DES_CBC. Prefer
919
// the earliest entry. When asked for "DES/CBC/PKCS5Padding", we
920
// return a CKM_DES_CBC_PAD.
921
final Map<Descriptor,Integer> supportedAlgs =
922
new HashMap<Descriptor,Integer>();
923
for (int i = 0; i < supportedMechanisms.length; i++) {
924
long longMech = supportedMechanisms[i];
925
boolean isEnabled = config.isEnabled(longMech);
926
if (showInfo) {
927
CK_MECHANISM_INFO mechInfo =
928
p11.C_GetMechanismInfo(slotID, longMech);
929
System.out.println("Mechanism " +
930
Functions.getMechanismName(longMech) + ":");
931
if (isEnabled == false) {
932
System.out.println("DISABLED in configuration");
933
}
934
System.out.println(mechInfo);
935
}
936
if (isEnabled == false) {
937
continue;
938
}
939
// we do not know of mechs with the upper 32 bits set
940
if (longMech >>> 32 != 0) {
941
continue;
942
}
943
int mech = (int)longMech;
944
Integer integerMech = Integer.valueOf(mech);
945
List<Descriptor> ds = descriptors.get(integerMech);
946
if (ds == null) {
947
continue;
948
}
949
for (Descriptor d : ds) {
950
Integer oldMech = supportedAlgs.get(d);
951
if (oldMech == null) {
952
supportedAlgs.put(d, integerMech);
953
continue;
954
}
955
// See if there is something "more preferred"
956
// than what we currently have in the supportedAlgs
957
// map.
958
int intOldMech = oldMech.intValue();
959
for (int j = 0; j < d.mechanisms.length; j++) {
960
int nextMech = d.mechanisms[j];
961
if (mech == nextMech) {
962
supportedAlgs.put(d, integerMech);
963
break;
964
} else if (intOldMech == nextMech) {
965
break;
966
}
967
}
968
}
969
970
}
971
972
// register algorithms in provider
973
AccessController.doPrivileged(new PrivilegedAction<Object>() {
974
public Object run() {
975
for (Map.Entry<Descriptor,Integer> entry
976
: supportedAlgs.entrySet()) {
977
Descriptor d = entry.getKey();
978
int mechanism = entry.getValue().intValue();
979
Service s = d.service(token, mechanism);
980
putService(s);
981
}
982
if (((token.tokenInfo.flags & CKF_RNG) != 0)
983
&& config.isEnabled(PCKM_SECURERANDOM)
984
&& !token.sessionManager.lowMaxSessions()) {
985
// do not register SecureRandom if the token does
986
// not support many sessions. if we did, we might
987
// run out of sessions in the middle of a
988
// nextBytes() call where we cannot fail over.
989
putService(new P11Service(token, SR, "PKCS11",
990
"sun.security.pkcs11.P11SecureRandom", null,
991
PCKM_SECURERANDOM));
992
}
993
if (config.isEnabled(PCKM_KEYSTORE)) {
994
putService(new P11Service(token, KS, "PKCS11",
995
"sun.security.pkcs11.P11KeyStore",
996
s("PKCS11-" + config.getName()),
997
PCKM_KEYSTORE));
998
}
999
return null;
1000
}
1001
});
1002
1003
this.token = token;
1004
}
1005
1006
private static final class P11Service extends Service {
1007
1008
private final Token token;
1009
1010
private final long mechanism;
1011
1012
P11Service(Token token, String type, String algorithm,
1013
String className, String[] al, long mechanism) {
1014
super(token.provider, type, algorithm, className, toList(al), null);
1015
this.token = token;
1016
this.mechanism = mechanism & 0xFFFFFFFFL;
1017
}
1018
1019
private static List<String> toList(String[] aliases) {
1020
return (aliases == null) ? null : Arrays.asList(aliases);
1021
}
1022
1023
public Object newInstance(Object param)
1024
throws NoSuchAlgorithmException {
1025
if (token.isValid() == false) {
1026
throw new NoSuchAlgorithmException("Token has been removed");
1027
}
1028
try {
1029
return newInstance0(param);
1030
} catch (PKCS11Exception e) {
1031
throw new NoSuchAlgorithmException(e);
1032
}
1033
}
1034
1035
public Object newInstance0(Object param) throws
1036
PKCS11Exception, NoSuchAlgorithmException {
1037
String algorithm = getAlgorithm();
1038
String type = getType();
1039
if (type == MD) {
1040
return new P11Digest(token, algorithm, mechanism);
1041
} else if (type == CIP) {
1042
if (algorithm.startsWith("RSA")) {
1043
return new P11RSACipher(token, algorithm, mechanism);
1044
} else if (algorithm.endsWith("GCM/NoPadding")) {
1045
return new P11AEADCipher(token, algorithm, mechanism);
1046
} else {
1047
return new P11Cipher(token, algorithm, mechanism);
1048
}
1049
} else if (type == SIG) {
1050
if (algorithm.indexOf("RSASSA-PSS") != -1) {
1051
return new P11PSSSignature(token, algorithm, mechanism);
1052
} else {
1053
return new P11Signature(token, algorithm, mechanism);
1054
}
1055
} else if (type == MAC) {
1056
return new P11Mac(token, algorithm, mechanism);
1057
} else if (type == KPG) {
1058
return new P11KeyPairGenerator(token, algorithm, mechanism);
1059
} else if (type == KA) {
1060
if (algorithm.equals("ECDH")) {
1061
return new P11ECDHKeyAgreement(token, algorithm, mechanism);
1062
} else {
1063
return new P11KeyAgreement(token, algorithm, mechanism);
1064
}
1065
} else if (type == KF) {
1066
return token.getKeyFactory(algorithm);
1067
} else if (type == SKF) {
1068
return new P11SecretKeyFactory(token, algorithm);
1069
} else if (type == KG) {
1070
// reference equality
1071
if (algorithm == "SunTlsRsaPremasterSecret") {
1072
return new P11TlsRsaPremasterSecretGenerator(
1073
token, algorithm, mechanism);
1074
} else if (algorithm == "SunTlsMasterSecret"
1075
|| algorithm == "SunTls12MasterSecret") {
1076
return new P11TlsMasterSecretGenerator(
1077
token, algorithm, mechanism);
1078
} else if (algorithm == "SunTlsKeyMaterial"
1079
|| algorithm == "SunTls12KeyMaterial") {
1080
return new P11TlsKeyMaterialGenerator(
1081
token, algorithm, mechanism);
1082
} else if (algorithm == "SunTlsPrf"
1083
|| algorithm == "SunTls12Prf") {
1084
return new P11TlsPrfGenerator(token, algorithm, mechanism);
1085
} else {
1086
return new P11KeyGenerator(token, algorithm, mechanism);
1087
}
1088
} else if (type == SR) {
1089
return token.getRandom();
1090
} else if (type == KS) {
1091
return token.getKeyStore();
1092
} else if (type == AGP) {
1093
if (algorithm == "EC") {
1094
return new sun.security.util.ECParameters();
1095
} else if (algorithm == "GCM") {
1096
return new sun.security.util.GCMParameters();
1097
} else {
1098
throw new NoSuchAlgorithmException("Unsupported algorithm: "
1099
+ algorithm);
1100
}
1101
} else {
1102
throw new NoSuchAlgorithmException("Unknown type: " + type);
1103
}
1104
}
1105
1106
public boolean supportsParameter(Object param) {
1107
if ((param == null) || (token.isValid() == false)) {
1108
return false;
1109
}
1110
if (param instanceof Key == false) {
1111
throw new InvalidParameterException("Parameter must be a Key");
1112
}
1113
String algorithm = getAlgorithm();
1114
String type = getType();
1115
Key key = (Key)param;
1116
String keyAlgorithm = key.getAlgorithm();
1117
// RSA signatures and cipher
1118
if (((type == CIP) && algorithm.startsWith("RSA"))
1119
|| (type == SIG) && (algorithm.indexOf("RSA") != -1)) {
1120
if (keyAlgorithm.equals("RSA") == false) {
1121
return false;
1122
}
1123
return isLocalKey(key)
1124
|| (key instanceof RSAPrivateKey)
1125
|| (key instanceof RSAPublicKey);
1126
}
1127
// EC
1128
if (((type == KA) && algorithm.equals("ECDH"))
1129
|| ((type == SIG) && algorithm.endsWith("ECDSA"))) {
1130
if (keyAlgorithm.equals("EC") == false) {
1131
return false;
1132
}
1133
return isLocalKey(key)
1134
|| (key instanceof ECPrivateKey)
1135
|| (key instanceof ECPublicKey);
1136
}
1137
// DSA signatures
1138
if ((type == SIG) && algorithm.endsWith("DSA")) {
1139
if (keyAlgorithm.equals("DSA") == false) {
1140
return false;
1141
}
1142
return isLocalKey(key)
1143
|| (key instanceof DSAPrivateKey)
1144
|| (key instanceof DSAPublicKey);
1145
}
1146
// MACs and symmetric ciphers
1147
if ((type == CIP) || (type == MAC)) {
1148
// do not check algorithm name, mismatch is unlikely anyway
1149
return isLocalKey(key) || "RAW".equals(key.getFormat());
1150
}
1151
// DH key agreement
1152
if (type == KA) {
1153
if (keyAlgorithm.equals("DH") == false) {
1154
return false;
1155
}
1156
return isLocalKey(key)
1157
|| (key instanceof DHPrivateKey)
1158
|| (key instanceof DHPublicKey);
1159
}
1160
// should not reach here,
1161
// unknown engine type or algorithm
1162
throw new AssertionError
1163
("SunPKCS11 error: " + type + ", " + algorithm);
1164
}
1165
1166
private boolean isLocalKey(Key key) {
1167
return (key instanceof P11Key) && (((P11Key)key).token == token);
1168
}
1169
1170
public String toString() {
1171
return super.toString() +
1172
" (" + Functions.getMechanismName(mechanism) + ")";
1173
}
1174
1175
}
1176
1177
/**
1178
* Log in to this provider.
1179
*
1180
* <p> If the token expects a PIN to be supplied by the caller,
1181
* the <code>handler</code> implementation must support
1182
* a <code>PasswordCallback</code>.
1183
*
1184
* <p> To determine if the token supports a protected authentication path,
1185
* the CK_TOKEN_INFO flag, CKF_PROTECTED_AUTHENTICATION_PATH, is consulted.
1186
*
1187
* @param subject this parameter is ignored
1188
* @param handler the <code>CallbackHandler</code> used by
1189
* this provider to communicate with the caller
1190
*
1191
* @exception LoginException if the login operation fails
1192
* @exception SecurityException if the does not pass a security check for
1193
* <code>SecurityPermission("authProvider.<i>name</i>")</code>,
1194
* where <i>name</i> is the value returned by
1195
* this provider's <code>getName</code> method
1196
*/
1197
public void login(Subject subject, CallbackHandler handler)
1198
throws LoginException {
1199
1200
// security check
1201
1202
SecurityManager sm = System.getSecurityManager();
1203
if (sm != null) {
1204
if (debug != null) {
1205
debug.println("checking login permission");
1206
}
1207
sm.checkPermission(new SecurityPermission
1208
("authProvider." + this.getName()));
1209
}
1210
1211
if (hasValidToken() == false) {
1212
throw new LoginException("No token present");
1213
}
1214
1215
// see if a login is required
1216
1217
if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) {
1218
if (debug != null) {
1219
debug.println("login operation not required for token - " +
1220
"ignoring login request");
1221
}
1222
return;
1223
}
1224
1225
// see if user already logged in
1226
1227
try {
1228
if (token.isLoggedInNow(null)) {
1229
// user already logged in
1230
if (debug != null) {
1231
debug.println("user already logged in");
1232
}
1233
return;
1234
}
1235
} catch (PKCS11Exception e) {
1236
// ignore - fall thru and attempt login
1237
}
1238
1239
// get the pin if necessary
1240
1241
char[] pin = null;
1242
if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
1243
1244
// get password
1245
1246
CallbackHandler myHandler = getCallbackHandler(handler);
1247
if (myHandler == null) {
1248
// XXX PolicyTool is dependent on this message text
1249
throw new LoginException
1250
("no password provided, and no callback handler " +
1251
"available for retrieving password");
1252
}
1253
1254
java.text.MessageFormat form = new java.text.MessageFormat
1255
(ResourcesMgr.getString
1256
("PKCS11.Token.providerName.Password."));
1257
Object[] source = { getName() };
1258
1259
PasswordCallback pcall = new PasswordCallback(form.format(source),
1260
false);
1261
Callback[] callbacks = { pcall };
1262
try {
1263
myHandler.handle(callbacks);
1264
} catch (Exception e) {
1265
LoginException le = new LoginException
1266
("Unable to perform password callback");
1267
le.initCause(e);
1268
throw le;
1269
}
1270
1271
pin = pcall.getPassword();
1272
pcall.clearPassword();
1273
if (pin == null) {
1274
if (debug != null) {
1275
debug.println("caller passed NULL pin");
1276
}
1277
}
1278
}
1279
1280
// perform token login
1281
1282
Session session = null;
1283
try {
1284
session = token.getOpSession();
1285
1286
// pin is NULL if using CKF_PROTECTED_AUTHENTICATION_PATH
1287
p11.C_Login(session.id(), CKU_USER, pin);
1288
if (debug != null) {
1289
debug.println("login succeeded");
1290
}
1291
} catch (PKCS11Exception pe) {
1292
if (pe.getErrorCode() == CKR_USER_ALREADY_LOGGED_IN) {
1293
// let this one go
1294
if (debug != null) {
1295
debug.println("user already logged in");
1296
}
1297
return;
1298
} else if (pe.getErrorCode() == CKR_PIN_INCORRECT) {
1299
FailedLoginException fle = new FailedLoginException();
1300
fle.initCause(pe);
1301
throw fle;
1302
} else {
1303
LoginException le = new LoginException();
1304
le.initCause(pe);
1305
throw le;
1306
}
1307
} finally {
1308
token.releaseSession(session);
1309
if (pin != null) {
1310
Arrays.fill(pin, ' ');
1311
}
1312
}
1313
1314
// we do not store the PIN in the subject for now
1315
}
1316
1317
/**
1318
* Log out from this provider
1319
*
1320
* @exception LoginException if the logout operation fails
1321
* @exception SecurityException if the does not pass a security check for
1322
* <code>SecurityPermission("authProvider.<i>name</i>")</code>,
1323
* where <i>name</i> is the value returned by
1324
* this provider's <code>getName</code> method
1325
*/
1326
public void logout() throws LoginException {
1327
1328
// security check
1329
1330
SecurityManager sm = System.getSecurityManager();
1331
if (sm != null) {
1332
sm.checkPermission
1333
(new SecurityPermission("authProvider." + this.getName()));
1334
}
1335
1336
if (hasValidToken() == false) {
1337
// app may call logout for cleanup, allow
1338
return;
1339
}
1340
1341
if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) {
1342
if (debug != null) {
1343
debug.println("logout operation not required for token - " +
1344
"ignoring logout request");
1345
}
1346
return;
1347
}
1348
1349
try {
1350
if (token.isLoggedInNow(null) == false) {
1351
if (debug != null) {
1352
debug.println("user not logged in");
1353
}
1354
return;
1355
}
1356
} catch (PKCS11Exception e) {
1357
// ignore
1358
}
1359
1360
// perform token logout
1361
1362
Session session = null;
1363
try {
1364
session = token.getOpSession();
1365
p11.C_Logout(session.id());
1366
if (debug != null) {
1367
debug.println("logout succeeded");
1368
}
1369
} catch (PKCS11Exception pe) {
1370
if (pe.getErrorCode() == CKR_USER_NOT_LOGGED_IN) {
1371
// let this one go
1372
if (debug != null) {
1373
debug.println("user not logged in");
1374
}
1375
return;
1376
}
1377
LoginException le = new LoginException();
1378
le.initCause(pe);
1379
throw le;
1380
} finally {
1381
token.releaseSession(session);
1382
}
1383
}
1384
1385
/**
1386
* Set a <code>CallbackHandler</code>
1387
*
1388
* <p> The provider uses this handler if one is not passed to the
1389
* <code>login</code> method. The provider also uses this handler
1390
* if it invokes <code>login</code> on behalf of callers.
1391
* In either case if a handler is not set via this method,
1392
* the provider queries the
1393
* <i>auth.login.defaultCallbackHandler</i> security property
1394
* for the fully qualified class name of a default handler implementation.
1395
* If the security property is not set,
1396
* the provider is assumed to have alternative means
1397
* for obtaining authentication information.
1398
*
1399
* @param handler a <code>CallbackHandler</code> for obtaining
1400
* authentication information, which may be <code>null</code>
1401
*
1402
* @exception SecurityException if the caller does not pass a
1403
* security check for
1404
* <code>SecurityPermission("authProvider.<i>name</i>")</code>,
1405
* where <i>name</i> is the value returned by
1406
* this provider's <code>getName</code> method
1407
*/
1408
public void setCallbackHandler(CallbackHandler handler) {
1409
1410
// security check
1411
1412
SecurityManager sm = System.getSecurityManager();
1413
if (sm != null) {
1414
sm.checkPermission
1415
(new SecurityPermission("authProvider." + this.getName()));
1416
}
1417
1418
synchronized (LOCK_HANDLER) {
1419
pHandler = handler;
1420
}
1421
}
1422
1423
private CallbackHandler getCallbackHandler(CallbackHandler handler) {
1424
1425
// get default handler if necessary
1426
1427
if (handler != null) {
1428
return handler;
1429
}
1430
1431
if (debug != null) {
1432
debug.println("getting provider callback handler");
1433
}
1434
1435
synchronized (LOCK_HANDLER) {
1436
// see if handler was set via setCallbackHandler
1437
if (pHandler != null) {
1438
return pHandler;
1439
}
1440
1441
try {
1442
if (debug != null) {
1443
debug.println("getting default callback handler");
1444
}
1445
1446
CallbackHandler myHandler = AccessController.doPrivileged
1447
(new PrivilegedExceptionAction<CallbackHandler>() {
1448
public CallbackHandler run() throws Exception {
1449
1450
String defaultHandler =
1451
java.security.Security.getProperty
1452
("auth.login.defaultCallbackHandler");
1453
1454
if (defaultHandler == null ||
1455
defaultHandler.length() == 0) {
1456
1457
// ok
1458
if (debug != null) {
1459
debug.println("no default handler set");
1460
}
1461
return null;
1462
}
1463
1464
Class<?> c = Class.forName
1465
(defaultHandler,
1466
true,
1467
Thread.currentThread().getContextClassLoader());
1468
return (CallbackHandler)c.newInstance();
1469
}
1470
});
1471
1472
// save it
1473
pHandler = myHandler;
1474
return myHandler;
1475
1476
} catch (PrivilegedActionException pae) {
1477
// ok
1478
if (debug != null) {
1479
debug.println("Unable to load default callback handler");
1480
pae.printStackTrace();
1481
}
1482
}
1483
}
1484
return null;
1485
}
1486
1487
private Object writeReplace() throws ObjectStreamException {
1488
return new SunPKCS11Rep(this);
1489
}
1490
1491
/**
1492
* Serialized representation of the SunPKCS11 provider.
1493
*/
1494
private static class SunPKCS11Rep implements Serializable {
1495
1496
static final long serialVersionUID = -2896606995897745419L;
1497
1498
private final String providerName;
1499
1500
private final String configName;
1501
1502
SunPKCS11Rep(SunPKCS11 provider) throws NotSerializableException {
1503
providerName = provider.getName();
1504
configName = provider.configName;
1505
if (Security.getProvider(providerName) != provider) {
1506
throw new NotSerializableException("Only SunPKCS11 providers "
1507
+ "installed in java.security.Security can be serialized");
1508
}
1509
}
1510
1511
private Object readResolve() throws ObjectStreamException {
1512
SunPKCS11 p = (SunPKCS11)Security.getProvider(providerName);
1513
if ((p == null) || (p.configName.equals(configName) == false)) {
1514
throw new NotSerializableException("Could not find "
1515
+ providerName + " in installed providers");
1516
}
1517
return p;
1518
}
1519
}
1520
}
1521
1522