Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java
66646 views
1
/*
2
* Copyright (c) 2003, 2021, 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.PasswordCallback;
42
43
import com.sun.crypto.provider.ChaCha20Poly1305Parameters;
44
45
import jdk.internal.misc.InnocuousThread;
46
import sun.security.util.Debug;
47
import sun.security.util.ResourcesMgr;
48
import static sun.security.util.SecurityConstants.PROVIDER_VER;
49
import static sun.security.util.SecurityProviderConstants.getAliases;
50
51
import sun.security.pkcs11.Secmod.*;
52
53
import sun.security.pkcs11.wrapper.*;
54
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
55
import static sun.security.pkcs11.wrapper.PKCS11Exception.*;
56
57
/**
58
* PKCS#11 provider main class.
59
*
60
* @author Andreas Sterbenz
61
* @since 1.5
62
*/
63
public final class SunPKCS11 extends AuthProvider {
64
65
private static final long serialVersionUID = -1354835039035306505L;
66
67
static final Debug debug = Debug.getInstance("sunpkcs11");
68
// the PKCS11 object through which we make the native calls
69
final PKCS11 p11;
70
71
// configuration information
72
final Config config;
73
74
// id of the PKCS#11 slot we are using
75
final long slotID;
76
77
private CallbackHandler pHandler;
78
private final Object LOCK_HANDLER = new Object();
79
80
final boolean removable;
81
82
final Secmod.Module nssModule;
83
84
final boolean nssUseSecmodTrust;
85
86
private volatile Token token;
87
88
private TokenPoller poller;
89
90
static NativeResourceCleaner cleaner;
91
92
Token getToken() {
93
return token;
94
}
95
96
public SunPKCS11() {
97
super("SunPKCS11", PROVIDER_VER,
98
"Unconfigured and unusable PKCS11 provider");
99
p11 = null;
100
config = null;
101
slotID = 0;
102
pHandler = null;
103
removable = false;
104
nssModule = null;
105
nssUseSecmodTrust = false;
106
token = null;
107
poller = null;
108
}
109
110
@SuppressWarnings("removal")
111
@Override
112
public Provider configure(String configArg) throws InvalidParameterException {
113
final String newConfigName = checkNull(configArg);
114
try {
115
return AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
116
@Override
117
public SunPKCS11 run() throws Exception {
118
return new SunPKCS11(new Config(newConfigName));
119
}
120
});
121
} catch (PrivilegedActionException pae) {
122
InvalidParameterException ipe =
123
new InvalidParameterException("Error configuring SunPKCS11 provider");
124
throw (InvalidParameterException) ipe.initCause(pae.getException());
125
}
126
}
127
128
@Override
129
public boolean isConfigured() {
130
return (config != null);
131
}
132
133
private static <T> T checkNull(T obj) {
134
if (obj == null) {
135
throw new NullPointerException();
136
}
137
return obj;
138
}
139
140
// Used by Secmod
141
SunPKCS11(Config c) {
142
super("SunPKCS11-" + c.getName(), PROVIDER_VER, c.getDescription());
143
this.config = c;
144
145
if (debug != null) {
146
System.out.println("SunPKCS11 loading " + config.getFileName());
147
}
148
149
String library = config.getLibrary();
150
String functionList = config.getFunctionList();
151
long slotID = config.getSlotID();
152
int slotListIndex = config.getSlotListIndex();
153
154
boolean useSecmod = config.getNssUseSecmod();
155
boolean nssUseSecmodTrust = config.getNssUseSecmodTrust();
156
Secmod.Module nssModule = null;
157
158
//
159
// Initialization via Secmod. The way this works is as follows:
160
// SunPKCS11 is either in normal mode or in NSS Secmod mode.
161
// Secmod is activated by specifying one or more of the following
162
// options in the config file:
163
// nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule
164
//
165
// XXX add more explanation here
166
//
167
// If we are in Secmod mode and configured to use either the
168
// nssKeyStore or the nssTrustAnchors module, we automatically
169
// switch to using the NSS trust attributes for trusted certs
170
// (KeyStore).
171
//
172
173
if (useSecmod) {
174
// note: Config ensures library/slot/slotListIndex not specified
175
// in secmod mode.
176
Secmod secmod = Secmod.getInstance();
177
DbMode nssDbMode = config.getNssDbMode();
178
try {
179
String nssLibraryDirectory = config.getNssLibraryDirectory();
180
String nssSecmodDirectory = config.getNssSecmodDirectory();
181
boolean nssOptimizeSpace = config.getNssOptimizeSpace();
182
183
if (secmod.isInitialized()) {
184
if (nssSecmodDirectory != null) {
185
String s = secmod.getConfigDir();
186
if ((s != null) &&
187
(s.equals(nssSecmodDirectory) == false)) {
188
throw new ProviderException("Secmod directory "
189
+ nssSecmodDirectory
190
+ " invalid, NSS already initialized with "
191
+ s);
192
}
193
}
194
if (nssLibraryDirectory != null) {
195
String s = secmod.getLibDir();
196
if ((s != null) &&
197
(s.equals(nssLibraryDirectory) == false)) {
198
throw new ProviderException("NSS library directory "
199
+ nssLibraryDirectory
200
+ " invalid, NSS already initialized with "
201
+ s);
202
}
203
}
204
} else {
205
if (nssDbMode != DbMode.NO_DB) {
206
if (nssSecmodDirectory == null) {
207
throw new ProviderException(
208
"Secmod not initialized and "
209
+ "nssSecmodDirectory not specified");
210
}
211
} else {
212
if (nssSecmodDirectory != null) {
213
throw new ProviderException(
214
"nssSecmodDirectory must not be "
215
+ "specified in noDb mode");
216
}
217
}
218
secmod.initialize(nssDbMode, nssSecmodDirectory,
219
nssLibraryDirectory, nssOptimizeSpace);
220
}
221
} catch (IOException e) {
222
// XXX which exception to throw
223
throw new ProviderException("Could not initialize NSS", e);
224
}
225
List<Secmod.Module> modules = secmod.getModules();
226
if (config.getShowInfo()) {
227
System.out.println("NSS modules: " + modules);
228
}
229
230
String moduleName = config.getNssModule();
231
if (moduleName == null) {
232
nssModule = secmod.getModule(ModuleType.FIPS);
233
if (nssModule != null) {
234
moduleName = "fips";
235
} else {
236
moduleName = (nssDbMode == DbMode.NO_DB) ?
237
"crypto" : "keystore";
238
}
239
}
240
if (moduleName.equals("fips")) {
241
nssModule = secmod.getModule(ModuleType.FIPS);
242
nssUseSecmodTrust = true;
243
functionList = "FC_GetFunctionList";
244
} else if (moduleName.equals("keystore")) {
245
nssModule = secmod.getModule(ModuleType.KEYSTORE);
246
nssUseSecmodTrust = true;
247
} else if (moduleName.equals("crypto")) {
248
nssModule = secmod.getModule(ModuleType.CRYPTO);
249
} else if (moduleName.equals("trustanchors")) {
250
// XXX should the option be called trustanchor or trustanchors??
251
nssModule = secmod.getModule(ModuleType.TRUSTANCHOR);
252
nssUseSecmodTrust = true;
253
} else if (moduleName.startsWith("external-")) {
254
int moduleIndex;
255
try {
256
moduleIndex = Integer.parseInt
257
(moduleName.substring("external-".length()));
258
} catch (NumberFormatException e) {
259
moduleIndex = -1;
260
}
261
if (moduleIndex < 1) {
262
throw new ProviderException
263
("Invalid external module: " + moduleName);
264
}
265
int k = 0;
266
for (Secmod.Module module : modules) {
267
if (module.getType() == ModuleType.EXTERNAL) {
268
if (++k == moduleIndex) {
269
nssModule = module;
270
break;
271
}
272
}
273
}
274
if (nssModule == null) {
275
throw new ProviderException("Invalid module " + moduleName
276
+ ": only " + k + " external NSS modules available");
277
}
278
} else {
279
throw new ProviderException(
280
"Unknown NSS module: " + moduleName);
281
}
282
if (nssModule == null) {
283
throw new ProviderException(
284
"NSS module not available: " + moduleName);
285
}
286
if (nssModule.hasInitializedProvider()) {
287
throw new ProviderException("Secmod module already configured");
288
}
289
library = nssModule.libraryName;
290
slotListIndex = nssModule.slot;
291
}
292
this.nssUseSecmodTrust = nssUseSecmodTrust;
293
this.nssModule = nssModule;
294
295
File libraryFile = new File(library);
296
// if the filename is a simple filename without path
297
// (e.g. "libpkcs11.so"), it may refer to a library somewhere on the
298
// OS library search path. Omit the test for file existence as that
299
// only looks in the current directory.
300
if (libraryFile.getName().equals(library) == false) {
301
if (new File(library).isFile() == false) {
302
String msg = "Library " + library + " does not exist";
303
if (config.getHandleStartupErrors() == Config.ERR_HALT) {
304
throw new ProviderException(msg);
305
} else {
306
throw new UnsupportedOperationException(msg);
307
}
308
}
309
}
310
311
try {
312
if (debug != null) {
313
debug.println("Initializing PKCS#11 library " + library);
314
}
315
CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
316
String nssArgs = config.getNssArgs();
317
if (nssArgs != null) {
318
initArgs.pReserved = nssArgs;
319
}
320
// request multithreaded access first
321
initArgs.flags = CKF_OS_LOCKING_OK;
322
PKCS11 tmpPKCS11;
323
try {
324
tmpPKCS11 = PKCS11.getInstance(
325
library, functionList, initArgs,
326
config.getOmitInitialize());
327
} catch (PKCS11Exception e) {
328
if (debug != null) {
329
debug.println("Multi-threaded initialization failed: " + e);
330
}
331
if (config.getAllowSingleThreadedModules() == false) {
332
throw e;
333
}
334
// fall back to single threaded access
335
if (nssArgs == null) {
336
// if possible, use null initArgs for better compatibility
337
initArgs = null;
338
} else {
339
initArgs.flags = 0;
340
}
341
tmpPKCS11 = PKCS11.getInstance(library,
342
functionList, initArgs, config.getOmitInitialize());
343
}
344
p11 = tmpPKCS11;
345
346
CK_INFO p11Info = p11.C_GetInfo();
347
if (p11Info.cryptokiVersion.major < 2) {
348
throw new ProviderException("Only PKCS#11 v2.0 and later "
349
+ "supported, library version is v" + p11Info.cryptokiVersion);
350
}
351
boolean showInfo = config.getShowInfo();
352
if (showInfo) {
353
System.out.println("Information for provider " + getName());
354
System.out.println("Library info:");
355
System.out.println(p11Info);
356
}
357
358
if ((slotID < 0) || showInfo) {
359
long[] slots = p11.C_GetSlotList(false);
360
if (showInfo) {
361
System.out.println("All slots: " + toString(slots));
362
slots = p11.C_GetSlotList(true);
363
System.out.println("Slots with tokens: " + toString(slots));
364
}
365
if (slotID < 0) {
366
if ((slotListIndex < 0)
367
|| (slotListIndex >= slots.length)) {
368
throw new ProviderException("slotListIndex is "
369
+ slotListIndex
370
+ " but token only has " + slots.length + " slots");
371
}
372
slotID = slots[slotListIndex];
373
}
374
}
375
this.slotID = slotID;
376
CK_SLOT_INFO slotInfo = p11.C_GetSlotInfo(slotID);
377
removable = (slotInfo.flags & CKF_REMOVABLE_DEVICE) != 0;
378
initToken(slotInfo);
379
if (nssModule != null) {
380
nssModule.setProvider(this);
381
}
382
} catch (Exception e) {
383
if (config.getHandleStartupErrors() == Config.ERR_IGNORE_ALL) {
384
throw new UnsupportedOperationException
385
("Initialization failed", e);
386
} else {
387
throw new ProviderException
388
("Initialization failed", e);
389
}
390
}
391
}
392
393
private static String toString(long[] longs) {
394
if (longs.length == 0) {
395
return "(none)";
396
}
397
StringBuilder sb = new StringBuilder();
398
sb.append(longs[0]);
399
for (int i = 1; i < longs.length; i++) {
400
sb.append(", ");
401
sb.append(longs[i]);
402
}
403
return sb.toString();
404
}
405
406
public boolean equals(Object obj) {
407
return this == obj;
408
}
409
410
public int hashCode() {
411
return System.identityHashCode(this);
412
}
413
414
private static final class Descriptor {
415
final String type;
416
final String algorithm;
417
final String className;
418
final List<String> aliases;
419
final int[] mechanisms;
420
421
private Descriptor(String type, String algorithm, String className,
422
List<String> aliases, int[] mechanisms) {
423
this.type = type;
424
this.algorithm = algorithm;
425
this.className = className;
426
this.aliases = aliases;
427
this.mechanisms = mechanisms;
428
}
429
private P11Service service(Token token, int mechanism) {
430
return new P11Service
431
(token, type, algorithm, className, aliases, mechanism);
432
}
433
public String toString() {
434
return type + "." + algorithm;
435
}
436
}
437
438
// Map from mechanism to List of Descriptors that should be
439
// registered if the mechanism is supported
440
private static final Map<Integer,List<Descriptor>> descriptors =
441
new HashMap<Integer,List<Descriptor>>();
442
443
private static int[] m(long m1) {
444
return new int[] {(int)m1};
445
}
446
447
private static int[] m(long m1, long m2) {
448
return new int[] {(int)m1, (int)m2};
449
}
450
451
private static int[] m(long m1, long m2, long m3) {
452
return new int[] {(int)m1, (int)m2, (int)m3};
453
}
454
455
private static int[] m(long m1, long m2, long m3, long m4) {
456
return new int[] {(int)m1, (int)m2, (int)m3, (int)m4};
457
}
458
459
private static void d(String type, String algorithm, String className,
460
int[] m) {
461
register(new Descriptor(type, algorithm, className, null, m));
462
}
463
464
private static void d(String type, String algorithm, String className,
465
List<String> aliases, int[] m) {
466
register(new Descriptor(type, algorithm, className, aliases, m));
467
}
468
469
private static void dA(String type, String algorithm, String className,
470
int[] m) {
471
register(new Descriptor(type, algorithm, className,
472
getAliases(algorithm), m));
473
}
474
475
private static void register(Descriptor d) {
476
for (int i = 0; i < d.mechanisms.length; i++) {
477
int m = d.mechanisms[i];
478
Integer key = Integer.valueOf(m);
479
List<Descriptor> list = descriptors.get(key);
480
if (list == null) {
481
list = new ArrayList<Descriptor>();
482
descriptors.put(key, list);
483
}
484
list.add(d);
485
}
486
}
487
488
private static final String MD = "MessageDigest";
489
490
private static final String SIG = "Signature";
491
492
private static final String KPG = "KeyPairGenerator";
493
494
private static final String KG = "KeyGenerator";
495
496
private static final String AGP = "AlgorithmParameters";
497
498
private static final String KF = "KeyFactory";
499
500
private static final String SKF = "SecretKeyFactory";
501
502
private static final String CIP = "Cipher";
503
504
private static final String MAC = "Mac";
505
506
private static final String KA = "KeyAgreement";
507
508
private static final String KS = "KeyStore";
509
510
private static final String SR = "SecureRandom";
511
512
static {
513
// names of all the implementation classes
514
// use local variables, only used here
515
String P11Digest = "sun.security.pkcs11.P11Digest";
516
String P11Mac = "sun.security.pkcs11.P11Mac";
517
String P11KeyPairGenerator = "sun.security.pkcs11.P11KeyPairGenerator";
518
String P11KeyGenerator = "sun.security.pkcs11.P11KeyGenerator";
519
String P11RSAKeyFactory = "sun.security.pkcs11.P11RSAKeyFactory";
520
String P11DSAKeyFactory = "sun.security.pkcs11.P11DSAKeyFactory";
521
String P11DHKeyFactory = "sun.security.pkcs11.P11DHKeyFactory";
522
String P11ECKeyFactory = "sun.security.pkcs11.P11ECKeyFactory";
523
String P11KeyAgreement = "sun.security.pkcs11.P11KeyAgreement";
524
String P11SecretKeyFactory = "sun.security.pkcs11.P11SecretKeyFactory";
525
String P11Cipher = "sun.security.pkcs11.P11Cipher";
526
String P11RSACipher = "sun.security.pkcs11.P11RSACipher";
527
String P11AEADCipher = "sun.security.pkcs11.P11AEADCipher";
528
String P11Signature = "sun.security.pkcs11.P11Signature";
529
String P11PSSSignature = "sun.security.pkcs11.P11PSSSignature";
530
531
// XXX register all aliases
532
533
d(MD, "MD2", P11Digest,
534
m(CKM_MD2));
535
d(MD, "MD5", P11Digest,
536
m(CKM_MD5));
537
dA(MD, "SHA-1", P11Digest,
538
m(CKM_SHA_1));
539
540
dA(MD, "SHA-224", P11Digest,
541
m(CKM_SHA224));
542
dA(MD, "SHA-256", P11Digest,
543
m(CKM_SHA256));
544
dA(MD, "SHA-384", P11Digest,
545
m(CKM_SHA384));
546
dA(MD, "SHA-512", P11Digest,
547
m(CKM_SHA512));
548
dA(MD, "SHA-512/224", P11Digest,
549
m(CKM_SHA512_224));
550
dA(MD, "SHA-512/256", P11Digest,
551
m(CKM_SHA512_256));
552
dA(MD, "SHA3-224", P11Digest,
553
m(CKM_SHA3_224));
554
dA(MD, "SHA3-256", P11Digest,
555
m(CKM_SHA3_256));
556
dA(MD, "SHA3-384", P11Digest,
557
m(CKM_SHA3_384));
558
dA(MD, "SHA3-512", P11Digest,
559
m(CKM_SHA3_512));
560
561
d(MAC, "HmacMD5", P11Mac,
562
m(CKM_MD5_HMAC));
563
dA(MAC, "HmacSHA1", P11Mac,
564
m(CKM_SHA_1_HMAC));
565
dA(MAC, "HmacSHA224", P11Mac,
566
m(CKM_SHA224_HMAC));
567
dA(MAC, "HmacSHA256", P11Mac,
568
m(CKM_SHA256_HMAC));
569
dA(MAC, "HmacSHA384", P11Mac,
570
m(CKM_SHA384_HMAC));
571
dA(MAC, "HmacSHA512", P11Mac,
572
m(CKM_SHA512_HMAC));
573
dA(MAC, "HmacSHA512/224", P11Mac,
574
m(CKM_SHA512_224_HMAC));
575
dA(MAC, "HmacSHA512/256", P11Mac,
576
m(CKM_SHA512_256_HMAC));
577
dA(MAC, "HmacSHA3-224", P11Mac,
578
m(CKM_SHA3_224_HMAC));
579
dA(MAC, "HmacSHA3-256", P11Mac,
580
m(CKM_SHA3_256_HMAC));
581
dA(MAC, "HmacSHA3-384", P11Mac,
582
m(CKM_SHA3_384_HMAC));
583
dA(MAC, "HmacSHA3-512", P11Mac,
584
m(CKM_SHA3_512_HMAC));
585
d(MAC, "SslMacMD5", P11Mac,
586
m(CKM_SSL3_MD5_MAC));
587
d(MAC, "SslMacSHA1", P11Mac,
588
m(CKM_SSL3_SHA1_MAC));
589
590
d(KPG, "RSA", P11KeyPairGenerator,
591
getAliases("PKCS1"),
592
m(CKM_RSA_PKCS_KEY_PAIR_GEN));
593
594
List<String> dhAlias = List.of("DiffieHellman");
595
596
dA(KPG, "DSA", P11KeyPairGenerator,
597
m(CKM_DSA_KEY_PAIR_GEN));
598
d(KPG, "DH", P11KeyPairGenerator,
599
dhAlias,
600
m(CKM_DH_PKCS_KEY_PAIR_GEN));
601
d(KPG, "EC", P11KeyPairGenerator,
602
m(CKM_EC_KEY_PAIR_GEN));
603
604
dA(KG, "ARCFOUR", P11KeyGenerator,
605
m(CKM_RC4_KEY_GEN));
606
d(KG, "DES", P11KeyGenerator,
607
m(CKM_DES_KEY_GEN));
608
d(KG, "DESede", P11KeyGenerator,
609
m(CKM_DES3_KEY_GEN, CKM_DES2_KEY_GEN));
610
d(KG, "AES", P11KeyGenerator,
611
m(CKM_AES_KEY_GEN));
612
d(KG, "Blowfish", P11KeyGenerator,
613
m(CKM_BLOWFISH_KEY_GEN));
614
d(KG, "ChaCha20", P11KeyGenerator,
615
m(CKM_CHACHA20_KEY_GEN));
616
d(KG, "HmacMD5", P11KeyGenerator, // 1.3.6.1.5.5.8.1.1
617
m(CKM_GENERIC_SECRET_KEY_GEN));
618
dA(KG, "HmacSHA1", P11KeyGenerator,
619
m(CKM_SHA_1_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
620
dA(KG, "HmacSHA224", P11KeyGenerator,
621
m(CKM_SHA224_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
622
dA(KG, "HmacSHA256", P11KeyGenerator,
623
m(CKM_SHA256_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
624
dA(KG, "HmacSHA384", P11KeyGenerator,
625
m(CKM_SHA384_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
626
dA(KG, "HmacSHA512", P11KeyGenerator,
627
m(CKM_SHA512_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
628
dA(KG, "HmacSHA512/224", P11KeyGenerator,
629
m(CKM_SHA512_224_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
630
dA(KG, "HmacSHA512/256", P11KeyGenerator,
631
m(CKM_SHA512_256_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
632
dA(KG, "HmacSHA3-224", P11KeyGenerator,
633
m(CKM_SHA3_224_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
634
dA(KG, "HmacSHA3-256", P11KeyGenerator,
635
m(CKM_SHA3_256_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
636
dA(KG, "HmacSHA3-384", P11KeyGenerator,
637
m(CKM_SHA3_384_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
638
dA(KG, "HmacSHA3-512", P11KeyGenerator,
639
m(CKM_SHA3_512_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN));
640
641
// register (Secret)KeyFactories if there are any mechanisms
642
// for a particular algorithm that we support
643
d(KF, "RSA", P11RSAKeyFactory,
644
getAliases("PKCS1"),
645
m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509));
646
dA(KF, "DSA", P11DSAKeyFactory,
647
m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1));
648
d(KF, "DH", P11DHKeyFactory,
649
dhAlias,
650
m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
651
d(KF, "EC", P11ECKeyFactory,
652
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
653
CKM_ECDSA, CKM_ECDSA_SHA1));
654
655
// AlgorithmParameters for EC.
656
// Only needed until we have an EC implementation in the SUN provider.
657
dA(AGP, "EC", "sun.security.util.ECParameters",
658
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
659
CKM_ECDSA, CKM_ECDSA_SHA1));
660
661
662
d(AGP, "GCM", "sun.security.util.GCMParameters",
663
m(CKM_AES_GCM));
664
665
dA(AGP, "ChaCha20-Poly1305",
666
"com.sun.crypto.provider.ChaCha20Poly1305Parameters",
667
m(CKM_CHACHA20_POLY1305));
668
669
d(KA, "DH", P11KeyAgreement,
670
dhAlias,
671
m(CKM_DH_PKCS_DERIVE));
672
d(KA, "ECDH", "sun.security.pkcs11.P11ECDHKeyAgreement",
673
m(CKM_ECDH1_DERIVE));
674
675
dA(SKF, "ARCFOUR", P11SecretKeyFactory,
676
m(CKM_RC4));
677
d(SKF, "DES", P11SecretKeyFactory,
678
m(CKM_DES_CBC));
679
d(SKF, "DESede", P11SecretKeyFactory,
680
m(CKM_DES3_CBC));
681
dA(SKF, "AES", P11SecretKeyFactory,
682
m(CKM_AES_CBC));
683
d(SKF, "Blowfish", P11SecretKeyFactory,
684
m(CKM_BLOWFISH_CBC));
685
d(SKF, "ChaCha20", P11SecretKeyFactory,
686
m(CKM_CHACHA20_POLY1305));
687
688
// XXX attributes for Ciphers (supported modes, padding)
689
dA(CIP, "ARCFOUR", P11Cipher,
690
m(CKM_RC4));
691
d(CIP, "DES/CBC/NoPadding", P11Cipher,
692
m(CKM_DES_CBC));
693
d(CIP, "DES/CBC/PKCS5Padding", P11Cipher,
694
m(CKM_DES_CBC_PAD, CKM_DES_CBC));
695
d(CIP, "DES/ECB/NoPadding", P11Cipher,
696
m(CKM_DES_ECB));
697
d(CIP, "DES/ECB/PKCS5Padding", P11Cipher,
698
List.of("DES"),
699
m(CKM_DES_ECB));
700
701
d(CIP, "DESede/CBC/NoPadding", P11Cipher,
702
m(CKM_DES3_CBC));
703
d(CIP, "DESede/CBC/PKCS5Padding", P11Cipher,
704
m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
705
d(CIP, "DESede/ECB/NoPadding", P11Cipher,
706
m(CKM_DES3_ECB));
707
d(CIP, "DESede/ECB/PKCS5Padding", P11Cipher,
708
List.of("DESede"),
709
m(CKM_DES3_ECB));
710
d(CIP, "AES/CBC/NoPadding", P11Cipher,
711
m(CKM_AES_CBC));
712
dA(CIP, "AES_128/CBC/NoPadding", P11Cipher,
713
m(CKM_AES_CBC));
714
dA(CIP, "AES_192/CBC/NoPadding", P11Cipher,
715
m(CKM_AES_CBC));
716
dA(CIP, "AES_256/CBC/NoPadding", P11Cipher,
717
m(CKM_AES_CBC));
718
d(CIP, "AES/CBC/PKCS5Padding", P11Cipher,
719
m(CKM_AES_CBC_PAD, CKM_AES_CBC));
720
d(CIP, "AES/ECB/NoPadding", P11Cipher,
721
m(CKM_AES_ECB));
722
dA(CIP, "AES_128/ECB/NoPadding", P11Cipher,
723
m(CKM_AES_ECB));
724
dA(CIP, "AES_192/ECB/NoPadding", P11Cipher,
725
m(CKM_AES_ECB));
726
dA(CIP, "AES_256/ECB/NoPadding", P11Cipher,
727
m(CKM_AES_ECB));
728
d(CIP, "AES/ECB/PKCS5Padding", P11Cipher,
729
List.of("AES"),
730
m(CKM_AES_ECB));
731
d(CIP, "AES/CTR/NoPadding", P11Cipher,
732
m(CKM_AES_CTR));
733
734
d(CIP, "AES/GCM/NoPadding", P11AEADCipher,
735
m(CKM_AES_GCM));
736
dA(CIP, "AES_128/GCM/NoPadding", P11AEADCipher,
737
m(CKM_AES_GCM));
738
dA(CIP, "AES_192/GCM/NoPadding", P11AEADCipher,
739
m(CKM_AES_GCM));
740
dA(CIP, "AES_256/GCM/NoPadding", P11AEADCipher,
741
m(CKM_AES_GCM));
742
743
d(CIP, "Blowfish/CBC/NoPadding", P11Cipher,
744
m(CKM_BLOWFISH_CBC));
745
d(CIP, "Blowfish/CBC/PKCS5Padding", P11Cipher,
746
m(CKM_BLOWFISH_CBC));
747
748
dA(CIP, "ChaCha20-Poly1305", P11AEADCipher,
749
m(CKM_CHACHA20_POLY1305));
750
751
d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher,
752
List.of("RSA"),
753
m(CKM_RSA_PKCS));
754
d(CIP, "RSA/ECB/NoPadding", P11RSACipher,
755
m(CKM_RSA_X_509));
756
757
d(SIG, "RawDSA", P11Signature,
758
List.of("NONEwithDSA"),
759
m(CKM_DSA));
760
dA(SIG, "SHA1withDSA", P11Signature,
761
m(CKM_DSA_SHA1, CKM_DSA));
762
dA(SIG, "SHA224withDSA", P11Signature,
763
m(CKM_DSA_SHA224));
764
dA(SIG, "SHA256withDSA", P11Signature,
765
m(CKM_DSA_SHA256));
766
dA(SIG, "SHA384withDSA", P11Signature,
767
m(CKM_DSA_SHA384));
768
dA(SIG, "SHA512withDSA", P11Signature,
769
m(CKM_DSA_SHA512));
770
dA(SIG, "SHA3-224withDSA", P11Signature,
771
m(CKM_DSA_SHA3_224));
772
dA(SIG, "SHA3-256withDSA", P11Signature,
773
m(CKM_DSA_SHA3_256));
774
dA(SIG, "SHA3-384withDSA", P11Signature,
775
m(CKM_DSA_SHA3_384));
776
dA(SIG, "SHA3-512withDSA", P11Signature,
777
m(CKM_DSA_SHA3_512));
778
d(SIG, "RawDSAinP1363Format", P11Signature,
779
List.of("NONEwithDSAinP1363Format"),
780
m(CKM_DSA));
781
d(SIG, "DSAinP1363Format", P11Signature,
782
List.of("SHA1withDSAinP1363Format"),
783
m(CKM_DSA_SHA1, CKM_DSA));
784
d(SIG, "SHA224withDSAinP1363Format", P11Signature,
785
m(CKM_DSA_SHA224));
786
d(SIG, "SHA256withDSAinP1363Format", P11Signature,
787
m(CKM_DSA_SHA256));
788
d(SIG, "SHA384withDSAinP1363Format", P11Signature,
789
m(CKM_DSA_SHA384));
790
d(SIG, "SHA512withDSAinP1363Format", P11Signature,
791
m(CKM_DSA_SHA512));
792
d(SIG, "SHA3-224withDSAinP1363Format", P11Signature,
793
m(CKM_DSA_SHA3_224));
794
d(SIG, "SHA3-256withDSAinP1363Format", P11Signature,
795
m(CKM_DSA_SHA3_256));
796
d(SIG, "SHA3-384withDSAinP1363Format", P11Signature,
797
m(CKM_DSA_SHA3_384));
798
d(SIG, "SHA3-512withDSAinP1363Format", P11Signature,
799
m(CKM_DSA_SHA3_512));
800
d(SIG, "NONEwithECDSA", P11Signature,
801
m(CKM_ECDSA));
802
dA(SIG, "SHA1withECDSA", P11Signature,
803
m(CKM_ECDSA_SHA1, CKM_ECDSA));
804
dA(SIG, "SHA224withECDSA", P11Signature,
805
m(CKM_ECDSA_SHA224, CKM_ECDSA));
806
dA(SIG, "SHA256withECDSA", P11Signature,
807
m(CKM_ECDSA_SHA256, CKM_ECDSA));
808
dA(SIG, "SHA384withECDSA", P11Signature,
809
m(CKM_ECDSA_SHA384, CKM_ECDSA));
810
dA(SIG, "SHA512withECDSA", P11Signature,
811
m(CKM_ECDSA_SHA512, CKM_ECDSA));
812
dA(SIG, "SHA3-224withECDSA", P11Signature,
813
m(CKM_ECDSA_SHA3_224, CKM_ECDSA));
814
dA(SIG, "SHA3-256withECDSA", P11Signature,
815
m(CKM_ECDSA_SHA3_256, CKM_ECDSA));
816
dA(SIG, "SHA3-384withECDSA", P11Signature,
817
m(CKM_ECDSA_SHA3_384, CKM_ECDSA));
818
dA(SIG, "SHA3-512withECDSA", P11Signature,
819
m(CKM_ECDSA_SHA3_512, CKM_ECDSA));
820
d(SIG, "NONEwithECDSAinP1363Format", P11Signature,
821
m(CKM_ECDSA));
822
d(SIG, "SHA1withECDSAinP1363Format", P11Signature,
823
m(CKM_ECDSA_SHA1, CKM_ECDSA));
824
d(SIG, "SHA224withECDSAinP1363Format", P11Signature,
825
m(CKM_ECDSA_SHA224, CKM_ECDSA));
826
d(SIG, "SHA256withECDSAinP1363Format", P11Signature,
827
m(CKM_ECDSA_SHA256, CKM_ECDSA));
828
d(SIG, "SHA384withECDSAinP1363Format", P11Signature,
829
m(CKM_ECDSA_SHA384, CKM_ECDSA));
830
d(SIG, "SHA512withECDSAinP1363Format", P11Signature,
831
m(CKM_ECDSA_SHA512, CKM_ECDSA));
832
d(SIG, "SHA3-224withECDSAinP1363Format", P11Signature,
833
m(CKM_ECDSA_SHA3_224, CKM_ECDSA));
834
d(SIG, "SHA3-256withECDSAinP1363Format", P11Signature,
835
m(CKM_ECDSA_SHA3_256, CKM_ECDSA));
836
d(SIG, "SHA3-384withECDSAinP1363Format", P11Signature,
837
m(CKM_ECDSA_SHA3_384, CKM_ECDSA));
838
d(SIG, "SHA3-512withECDSAinP1363Format", P11Signature,
839
m(CKM_ECDSA_SHA3_512, CKM_ECDSA));
840
841
dA(SIG, "MD2withRSA", P11Signature,
842
m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
843
dA(SIG, "MD5withRSA", P11Signature,
844
m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
845
dA(SIG, "SHA1withRSA", P11Signature,
846
m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
847
dA(SIG, "SHA224withRSA", P11Signature,
848
m(CKM_SHA224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
849
dA(SIG, "SHA256withRSA", P11Signature,
850
m(CKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
851
dA(SIG, "SHA384withRSA", P11Signature,
852
m(CKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
853
dA(SIG, "SHA512withRSA", P11Signature,
854
m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
855
dA(SIG, "SHA3-224withRSA", P11Signature,
856
m(CKM_SHA3_224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
857
dA(SIG, "SHA3-256withRSA", P11Signature,
858
m(CKM_SHA3_256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
859
dA(SIG, "SHA3-384withRSA", P11Signature,
860
m(CKM_SHA3_384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
861
dA(SIG, "SHA3-512withRSA", P11Signature,
862
m(CKM_SHA3_512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
863
dA(SIG, "RSASSA-PSS", P11PSSSignature,
864
m(CKM_RSA_PKCS_PSS));
865
d(SIG, "SHA1withRSASSA-PSS", P11PSSSignature,
866
m(CKM_SHA1_RSA_PKCS_PSS));
867
d(SIG, "SHA224withRSASSA-PSS", P11PSSSignature,
868
m(CKM_SHA224_RSA_PKCS_PSS));
869
d(SIG, "SHA256withRSASSA-PSS", P11PSSSignature,
870
m(CKM_SHA256_RSA_PKCS_PSS));
871
d(SIG, "SHA384withRSASSA-PSS", P11PSSSignature,
872
m(CKM_SHA384_RSA_PKCS_PSS));
873
d(SIG, "SHA512withRSASSA-PSS", P11PSSSignature,
874
m(CKM_SHA512_RSA_PKCS_PSS));
875
d(SIG, "SHA3-224withRSASSA-PSS", P11PSSSignature,
876
m(CKM_SHA3_224_RSA_PKCS_PSS));
877
d(SIG, "SHA3-256withRSASSA-PSS", P11PSSSignature,
878
m(CKM_SHA3_256_RSA_PKCS_PSS));
879
d(SIG, "SHA3-384withRSASSA-PSS", P11PSSSignature,
880
m(CKM_SHA3_384_RSA_PKCS_PSS));
881
d(SIG, "SHA3-512withRSASSA-PSS", P11PSSSignature,
882
m(CKM_SHA3_512_RSA_PKCS_PSS));
883
884
d(KG, "SunTlsRsaPremasterSecret",
885
"sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
886
List.of("SunTls12RsaPremasterSecret"),
887
m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN));
888
d(KG, "SunTlsMasterSecret",
889
"sun.security.pkcs11.P11TlsMasterSecretGenerator",
890
m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE,
891
CKM_SSL3_MASTER_KEY_DERIVE_DH,
892
CKM_TLS_MASTER_KEY_DERIVE_DH));
893
d(KG, "SunTls12MasterSecret",
894
"sun.security.pkcs11.P11TlsMasterSecretGenerator",
895
m(CKM_TLS12_MASTER_KEY_DERIVE, CKM_TLS12_MASTER_KEY_DERIVE_DH));
896
d(KG, "SunTlsKeyMaterial",
897
"sun.security.pkcs11.P11TlsKeyMaterialGenerator",
898
m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE));
899
d(KG, "SunTls12KeyMaterial",
900
"sun.security.pkcs11.P11TlsKeyMaterialGenerator",
901
m(CKM_TLS12_KEY_AND_MAC_DERIVE));
902
d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator",
903
m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL));
904
d(KG, "SunTls12Prf", "sun.security.pkcs11.P11TlsPrfGenerator",
905
m(CKM_TLS_MAC));
906
}
907
908
// background thread that periodically checks for token insertion
909
// if no token is present. We need to do that in a separate thread because
910
// the insertion check may block for quite a long time on some tokens.
911
private static class TokenPoller implements Runnable {
912
private final SunPKCS11 provider;
913
private volatile boolean enabled;
914
915
private TokenPoller(SunPKCS11 provider) {
916
this.provider = provider;
917
enabled = true;
918
}
919
@Override
920
public void run() {
921
int interval = provider.config.getInsertionCheckInterval();
922
while (enabled) {
923
try {
924
Thread.sleep(interval);
925
} catch (InterruptedException e) {
926
break;
927
}
928
if (enabled == false) {
929
break;
930
}
931
try {
932
provider.initToken(null);
933
} catch (PKCS11Exception e) {
934
// ignore
935
}
936
}
937
}
938
void disable() {
939
enabled = false;
940
}
941
}
942
943
// create the poller thread, if not already active
944
@SuppressWarnings("removal")
945
private void createPoller() {
946
if (poller != null) {
947
return;
948
}
949
poller = new TokenPoller(this);
950
Thread t = InnocuousThread.newSystemThread(
951
"Poller-" + getName(),
952
poller,
953
Thread.MIN_PRIORITY);
954
assert t.getContextClassLoader() == null;
955
t.setDaemon(true);
956
t.start();
957
958
}
959
960
// destroy the poller thread, if active
961
private void destroyPoller() {
962
if (poller != null) {
963
poller.disable();
964
poller = null;
965
}
966
}
967
968
private boolean hasValidToken() {
969
/* Commented out to work with Solaris softtoken impl which
970
returns 0-value flags, e.g. both REMOVABLE_DEVICE and
971
TOKEN_PRESENT are false, when it can't access the token.
972
if (removable == false) {
973
return true;
974
}
975
*/
976
Token token = this.token;
977
return (token != null) && token.isValid();
978
}
979
980
private class NativeResourceCleaner implements Runnable {
981
private long sleepMillis = config.getResourceCleanerShortInterval();
982
private int count = 0;
983
boolean keyRefFound, sessRefFound;
984
985
/*
986
* The cleaner.shortInterval and cleaner.longInterval properties
987
* may be defined in the pkcs11 config file and are specified in milliseconds
988
* Minimum value is 1000ms. Default values :
989
* cleaner.shortInterval : 2000ms
990
* cleaner.longInterval : 60000ms
991
*
992
* The cleaner thread runs at cleaner.shortInterval intervals
993
* while P11Key or Session references continue to be found for cleaning.
994
* If 100 iterations occur with no references being found, then the interval
995
* period moves to cleaner.longInterval value. The cleaner thread moves back
996
* to short interval checking if a resource is found
997
*/
998
@Override
999
public void run() {
1000
while (true) {
1001
try {
1002
Thread.sleep(sleepMillis);
1003
} catch (InterruptedException ie) {
1004
break;
1005
}
1006
keyRefFound = P11Key.drainRefQueue();
1007
sessRefFound = Session.drainRefQueue();
1008
if (!keyRefFound && !sessRefFound) {
1009
count++;
1010
if (count > 100) {
1011
// no reference freed for some time
1012
// increase the sleep time
1013
sleepMillis = config.getResourceCleanerLongInterval();
1014
}
1015
} else {
1016
count = 0;
1017
sleepMillis = config.getResourceCleanerShortInterval();
1018
}
1019
}
1020
}
1021
}
1022
1023
// create the cleaner thread, if not already active
1024
@SuppressWarnings("removal")
1025
private void createCleaner() {
1026
cleaner = new NativeResourceCleaner();
1027
Thread t = InnocuousThread.newSystemThread(
1028
"Cleanup-SunPKCS11",
1029
cleaner,
1030
Thread.MIN_PRIORITY);
1031
assert t.getContextClassLoader() == null;
1032
t.setDaemon(true);
1033
t.start();
1034
}
1035
1036
// destroy the token. Called if we detect that it has been removed
1037
@SuppressWarnings("removal")
1038
synchronized void uninitToken(Token token) {
1039
if (this.token != token) {
1040
// mismatch, our token must already be destroyed
1041
return;
1042
}
1043
destroyPoller();
1044
this.token = null;
1045
// unregister all algorithms
1046
AccessController.doPrivileged(new PrivilegedAction<Object>() {
1047
public Object run() {
1048
clear();
1049
return null;
1050
}
1051
});
1052
// keep polling for token insertion unless configured not to
1053
if (removable && !config.getDestroyTokenAfterLogout()) {
1054
createPoller();
1055
}
1056
}
1057
1058
private static boolean isLegacy(CK_MECHANISM_INFO mechInfo)
1059
throws PKCS11Exception {
1060
// assume full support if no mech info available
1061
// For vendor-specific mechanisms, often no mech info is provided
1062
boolean partialSupport = false;
1063
1064
if (mechInfo != null) {
1065
if ((mechInfo.flags & CKF_DECRYPT) != 0) {
1066
// non-legacy cipher mechs should support encryption
1067
partialSupport |= ((mechInfo.flags & CKF_ENCRYPT) == 0);
1068
}
1069
if ((mechInfo.flags & CKF_VERIFY) != 0) {
1070
// non-legacy signature mechs should support signing
1071
partialSupport |= ((mechInfo.flags & CKF_SIGN) == 0);
1072
}
1073
}
1074
return partialSupport;
1075
}
1076
1077
// test if a token is present and initialize this provider for it if so.
1078
// does nothing if no token is found
1079
// called from constructor and by poller
1080
private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception {
1081
if (slotInfo == null) {
1082
slotInfo = p11.C_GetSlotInfo(slotID);
1083
}
1084
if (removable && (slotInfo.flags & CKF_TOKEN_PRESENT) == 0) {
1085
createPoller();
1086
return;
1087
}
1088
destroyPoller();
1089
boolean showInfo = config.getShowInfo();
1090
if (showInfo) {
1091
System.out.println("Slot info for slot " + slotID + ":");
1092
System.out.println(slotInfo);
1093
}
1094
final Token token = new Token(this);
1095
if (showInfo) {
1096
System.out.println
1097
("Token info for token in slot " + slotID + ":");
1098
System.out.println(token.tokenInfo);
1099
}
1100
long[] supportedMechanisms = p11.C_GetMechanismList(slotID);
1101
1102
// Create a map from the various Descriptors to the "most
1103
// preferred" mechanism that was defined during the
1104
// static initialization. For example, DES/CBC/PKCS5Padding
1105
// could be mapped to CKM_DES_CBC_PAD or CKM_DES_CBC. Prefer
1106
// the earliest entry. When asked for "DES/CBC/PKCS5Padding", we
1107
// return a CKM_DES_CBC_PAD.
1108
final Map<Descriptor,Integer> supportedAlgs =
1109
new HashMap<Descriptor,Integer>();
1110
1111
for (int i = 0; i < supportedMechanisms.length; i++) {
1112
long longMech = supportedMechanisms[i];
1113
CK_MECHANISM_INFO mechInfo = token.getMechanismInfo(longMech);
1114
if (showInfo) {
1115
System.out.println("Mechanism " +
1116
Functions.getMechanismName(longMech) + ":");
1117
System.out.println(mechInfo == null?
1118
(Constants.INDENT + "info n/a") :
1119
mechInfo);
1120
}
1121
if (!config.isEnabled(longMech)) {
1122
if (showInfo) {
1123
System.out.println("DISABLED in configuration");
1124
}
1125
continue;
1126
}
1127
if (isLegacy(mechInfo)) {
1128
if (showInfo) {
1129
System.out.println("DISABLED due to legacy");
1130
}
1131
continue;
1132
}
1133
1134
// we do not know of mechs with the upper 32 bits set
1135
if (longMech >>> 32 != 0) {
1136
if (showInfo) {
1137
System.out.println("DISABLED due to unknown mech value");
1138
}
1139
continue;
1140
}
1141
int mech = (int)longMech;
1142
Integer integerMech = Integer.valueOf(mech);
1143
List<Descriptor> ds = descriptors.get(integerMech);
1144
if (ds == null) {
1145
continue;
1146
}
1147
for (Descriptor d : ds) {
1148
Integer oldMech = supportedAlgs.get(d);
1149
if (oldMech == null) {
1150
supportedAlgs.put(d, integerMech);
1151
continue;
1152
}
1153
// See if there is something "more preferred"
1154
// than what we currently have in the supportedAlgs
1155
// map.
1156
int intOldMech = oldMech.intValue();
1157
for (int j = 0; j < d.mechanisms.length; j++) {
1158
int nextMech = d.mechanisms[j];
1159
if (mech == nextMech) {
1160
supportedAlgs.put(d, integerMech);
1161
break;
1162
} else if (intOldMech == nextMech) {
1163
break;
1164
}
1165
}
1166
}
1167
1168
}
1169
1170
// register algorithms in provider
1171
@SuppressWarnings("removal")
1172
var dummy = AccessController.doPrivileged(new PrivilegedAction<Object>() {
1173
public Object run() {
1174
for (Map.Entry<Descriptor,Integer> entry
1175
: supportedAlgs.entrySet()) {
1176
Descriptor d = entry.getKey();
1177
int mechanism = entry.getValue().intValue();
1178
Service s = d.service(token, mechanism);
1179
putService(s);
1180
}
1181
if (((token.tokenInfo.flags & CKF_RNG) != 0)
1182
&& config.isEnabled(PCKM_SECURERANDOM)
1183
&& !token.sessionManager.lowMaxSessions()) {
1184
// do not register SecureRandom if the token does
1185
// not support many sessions. if we did, we might
1186
// run out of sessions in the middle of a
1187
// nextBytes() call where we cannot fail over.
1188
putService(new P11Service(token, SR, "PKCS11",
1189
"sun.security.pkcs11.P11SecureRandom", null,
1190
PCKM_SECURERANDOM));
1191
}
1192
if (config.isEnabled(PCKM_KEYSTORE)) {
1193
putService(new P11Service(token, KS, "PKCS11",
1194
"sun.security.pkcs11.P11KeyStore",
1195
List.of("PKCS11-" + config.getName()),
1196
PCKM_KEYSTORE));
1197
}
1198
return null;
1199
}
1200
});
1201
1202
this.token = token;
1203
if (cleaner == null) {
1204
createCleaner();
1205
}
1206
}
1207
1208
private static final class P11Service extends Service {
1209
1210
private final Token token;
1211
1212
private final long mechanism;
1213
1214
P11Service(Token token, String type, String algorithm,
1215
String className, List<String> al, long mechanism) {
1216
super(token.provider, type, algorithm, className, al,
1217
type.equals(SR) ? Map.of("ThreadSafe", "true") : null);
1218
this.token = token;
1219
this.mechanism = mechanism & 0xFFFFFFFFL;
1220
}
1221
1222
@Override
1223
public Object newInstance(Object param)
1224
throws NoSuchAlgorithmException {
1225
if (token.isValid() == false) {
1226
throw new NoSuchAlgorithmException("Token has been removed");
1227
}
1228
try {
1229
return newInstance0(param);
1230
} catch (PKCS11Exception e) {
1231
throw new NoSuchAlgorithmException(e);
1232
}
1233
}
1234
1235
public Object newInstance0(Object param) throws
1236
PKCS11Exception, NoSuchAlgorithmException {
1237
String algorithm = getAlgorithm();
1238
String type = getType();
1239
if (type == MD) {
1240
return new P11Digest(token, algorithm, mechanism);
1241
} else if (type == CIP) {
1242
if (algorithm.startsWith("RSA")) {
1243
return new P11RSACipher(token, algorithm, mechanism);
1244
} else if (algorithm.endsWith("GCM/NoPadding") ||
1245
algorithm.startsWith("ChaCha20-Poly1305")) {
1246
return new P11AEADCipher(token, algorithm, mechanism);
1247
} else {
1248
return new P11Cipher(token, algorithm, mechanism);
1249
}
1250
} else if (type == SIG) {
1251
if (algorithm.indexOf("RSASSA-PSS") != -1) {
1252
return new P11PSSSignature(token, algorithm, mechanism);
1253
} else {
1254
return new P11Signature(token, algorithm, mechanism);
1255
}
1256
} else if (type == MAC) {
1257
return new P11Mac(token, algorithm, mechanism);
1258
} else if (type == KPG) {
1259
return new P11KeyPairGenerator(token, algorithm, mechanism);
1260
} else if (type == KA) {
1261
if (algorithm.equals("ECDH")) {
1262
return new P11ECDHKeyAgreement(token, algorithm, mechanism);
1263
} else {
1264
return new P11KeyAgreement(token, algorithm, mechanism);
1265
}
1266
} else if (type == KF) {
1267
return token.getKeyFactory(algorithm);
1268
} else if (type == SKF) {
1269
return new P11SecretKeyFactory(token, algorithm);
1270
} else if (type == KG) {
1271
// reference equality
1272
if (algorithm == "SunTlsRsaPremasterSecret") {
1273
return new P11TlsRsaPremasterSecretGenerator(
1274
token, algorithm, mechanism);
1275
} else if (algorithm == "SunTlsMasterSecret"
1276
|| algorithm == "SunTls12MasterSecret") {
1277
return new P11TlsMasterSecretGenerator(
1278
token, algorithm, mechanism);
1279
} else if (algorithm == "SunTlsKeyMaterial"
1280
|| algorithm == "SunTls12KeyMaterial") {
1281
return new P11TlsKeyMaterialGenerator(
1282
token, algorithm, mechanism);
1283
} else if (algorithm == "SunTlsPrf"
1284
|| algorithm == "SunTls12Prf") {
1285
return new P11TlsPrfGenerator(token, algorithm, mechanism);
1286
} else {
1287
return new P11KeyGenerator(token, algorithm, mechanism);
1288
}
1289
} else if (type == SR) {
1290
return token.getRandom();
1291
} else if (type == KS) {
1292
return token.getKeyStore();
1293
} else if (type == AGP) {
1294
if (algorithm == "EC") {
1295
return new sun.security.util.ECParameters();
1296
} else if (algorithm == "GCM") {
1297
return new sun.security.util.GCMParameters();
1298
} else if (algorithm == "ChaCha20-Poly1305") {
1299
return new ChaCha20Poly1305Parameters(); // from SunJCE
1300
} else {
1301
throw new NoSuchAlgorithmException("Unsupported algorithm: "
1302
+ algorithm);
1303
}
1304
} else {
1305
throw new NoSuchAlgorithmException("Unknown type: " + type);
1306
}
1307
}
1308
1309
public boolean supportsParameter(Object param) {
1310
if ((param == null) || (token.isValid() == false)) {
1311
return false;
1312
}
1313
if (param instanceof Key == false) {
1314
throw new InvalidParameterException("Parameter must be a Key");
1315
}
1316
String algorithm = getAlgorithm();
1317
String type = getType();
1318
Key key = (Key)param;
1319
String keyAlgorithm = key.getAlgorithm();
1320
// RSA signatures and cipher
1321
if (((type == CIP) && algorithm.startsWith("RSA"))
1322
|| (type == SIG) && (algorithm.indexOf("RSA") != -1)) {
1323
if (keyAlgorithm.equals("RSA") == false) {
1324
return false;
1325
}
1326
return isLocalKey(key)
1327
|| (key instanceof RSAPrivateKey)
1328
|| (key instanceof RSAPublicKey);
1329
}
1330
// EC
1331
if (((type == KA) && algorithm.equals("ECDH"))
1332
|| ((type == SIG) && algorithm.contains("ECDSA"))) {
1333
if (keyAlgorithm.equals("EC") == false) {
1334
return false;
1335
}
1336
return isLocalKey(key)
1337
|| (key instanceof ECPrivateKey)
1338
|| (key instanceof ECPublicKey);
1339
}
1340
// DSA signatures
1341
if ((type == SIG) && algorithm.contains("DSA") &&
1342
!algorithm.contains("ECDSA")) {
1343
if (keyAlgorithm.equals("DSA") == false) {
1344
return false;
1345
}
1346
return isLocalKey(key)
1347
|| (key instanceof DSAPrivateKey)
1348
|| (key instanceof DSAPublicKey);
1349
}
1350
// MACs and symmetric ciphers
1351
if ((type == CIP) || (type == MAC)) {
1352
// do not check algorithm name, mismatch is unlikely anyway
1353
return isLocalKey(key) || "RAW".equals(key.getFormat());
1354
}
1355
// DH key agreement
1356
if (type == KA) {
1357
if (keyAlgorithm.equals("DH") == false) {
1358
return false;
1359
}
1360
return isLocalKey(key)
1361
|| (key instanceof DHPrivateKey)
1362
|| (key instanceof DHPublicKey);
1363
}
1364
// should not reach here,
1365
// unknown engine type or algorithm
1366
throw new AssertionError
1367
("SunPKCS11 error: " + type + ", " + algorithm);
1368
}
1369
1370
private boolean isLocalKey(Key key) {
1371
return (key instanceof P11Key) && (((P11Key)key).token == token);
1372
}
1373
1374
public String toString() {
1375
return super.toString() +
1376
" (" + Functions.getMechanismName(mechanism) + ")";
1377
}
1378
1379
}
1380
1381
/**
1382
* Log in to this provider.
1383
*
1384
* <p> If the token expects a PIN to be supplied by the caller,
1385
* the <code>handler</code> implementation must support
1386
* a <code>PasswordCallback</code>.
1387
*
1388
* <p> To determine if the token supports a protected authentication path,
1389
* the CK_TOKEN_INFO flag, CKF_PROTECTED_AUTHENTICATION_PATH, is consulted.
1390
*
1391
* @param subject this parameter is ignored
1392
* @param handler the <code>CallbackHandler</code> used by
1393
* this provider to communicate with the caller
1394
*
1395
* @throws IllegalStateException if the provider requires configuration
1396
* and Provider.configure has not been called
1397
* @throws LoginException if the login operation fails
1398
* @throws SecurityException if the does not pass a security check for
1399
* <code>SecurityPermission("authProvider.<i>name</i>")</code>,
1400
* where <i>name</i> is the value returned by
1401
* this provider's <code>getName</code> method
1402
*/
1403
public void login(Subject subject, CallbackHandler handler)
1404
throws LoginException {
1405
1406
if (!isConfigured()) {
1407
throw new IllegalStateException("Configuration is required");
1408
}
1409
1410
// security check
1411
@SuppressWarnings("removal")
1412
SecurityManager sm = System.getSecurityManager();
1413
if (sm != null) {
1414
if (debug != null) {
1415
debug.println("checking login permission");
1416
}
1417
sm.checkPermission(new SecurityPermission
1418
("authProvider." + this.getName()));
1419
}
1420
1421
if (!hasValidToken()) {
1422
throw new LoginException("No token present");
1423
1424
}
1425
1426
// see if a login is required
1427
if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) {
1428
if (debug != null) {
1429
debug.println("login operation not required for token - " +
1430
"ignoring login request");
1431
}
1432
return;
1433
}
1434
1435
// see if user already logged in
1436
1437
try {
1438
if (token.isLoggedInNow(null)) {
1439
// user already logged in
1440
if (debug != null) {
1441
debug.println("user already logged in");
1442
}
1443
return;
1444
}
1445
} catch (PKCS11Exception e) {
1446
// ignore - fall thru and attempt login
1447
}
1448
1449
// get the pin if necessary
1450
1451
char[] pin = null;
1452
if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
1453
1454
// get password
1455
1456
CallbackHandler myHandler = getCallbackHandler(handler);
1457
if (myHandler == null) {
1458
throw new LoginException
1459
("no password provided, and no callback handler " +
1460
"available for retrieving password");
1461
}
1462
1463
java.text.MessageFormat form = new java.text.MessageFormat
1464
(ResourcesMgr.getString
1465
("PKCS11.Token.providerName.Password."));
1466
Object[] source = { getName() };
1467
1468
PasswordCallback pcall = new PasswordCallback(form.format(source),
1469
false);
1470
Callback[] callbacks = { pcall };
1471
try {
1472
myHandler.handle(callbacks);
1473
} catch (Exception e) {
1474
LoginException le = new LoginException
1475
("Unable to perform password callback");
1476
le.initCause(e);
1477
throw le;
1478
}
1479
1480
pin = pcall.getPassword();
1481
pcall.clearPassword();
1482
if (pin == null) {
1483
if (debug != null) {
1484
debug.println("caller passed NULL pin");
1485
}
1486
}
1487
}
1488
1489
// perform token login
1490
1491
Session session = null;
1492
try {
1493
session = token.getOpSession();
1494
1495
// pin is NULL if using CKF_PROTECTED_AUTHENTICATION_PATH
1496
p11.C_Login(session.id(), CKU_USER, pin);
1497
if (debug != null) {
1498
debug.println("login succeeded");
1499
}
1500
} catch (PKCS11Exception pe) {
1501
if (pe.getErrorCode() == CKR_USER_ALREADY_LOGGED_IN) {
1502
// let this one go
1503
if (debug != null) {
1504
debug.println("user already logged in");
1505
}
1506
return;
1507
} else if (pe.getErrorCode() == CKR_PIN_INCORRECT) {
1508
FailedLoginException fle = new FailedLoginException();
1509
fle.initCause(pe);
1510
throw fle;
1511
} else {
1512
LoginException le = new LoginException();
1513
le.initCause(pe);
1514
throw le;
1515
}
1516
} finally {
1517
token.releaseSession(session);
1518
if (pin != null) {
1519
Arrays.fill(pin, ' ');
1520
}
1521
}
1522
1523
// we do not store the PIN in the subject for now
1524
}
1525
1526
/**
1527
* Log out from this provider
1528
*
1529
* @throws IllegalStateException if the provider requires configuration
1530
* and Provider.configure has not been called
1531
* @throws LoginException if the logout operation fails
1532
* @throws SecurityException if the does not pass a security check for
1533
* <code>SecurityPermission("authProvider.<i>name</i>")</code>,
1534
* where <i>name</i> is the value returned by
1535
* this provider's <code>getName</code> method
1536
*/
1537
public void logout() throws LoginException {
1538
if (!isConfigured()) {
1539
throw new IllegalStateException("Configuration is required");
1540
}
1541
1542
// security check
1543
@SuppressWarnings("removal")
1544
SecurityManager sm = System.getSecurityManager();
1545
if (sm != null) {
1546
sm.checkPermission
1547
(new SecurityPermission("authProvider." + this.getName()));
1548
}
1549
1550
if (hasValidToken() == false) {
1551
// app may call logout for cleanup, allow
1552
return;
1553
}
1554
1555
if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) {
1556
if (debug != null) {
1557
debug.println("logout operation not required for token - " +
1558
"ignoring logout request");
1559
}
1560
return;
1561
}
1562
1563
try {
1564
if (!token.isLoggedInNow(null)) {
1565
if (debug != null) {
1566
debug.println("user not logged in");
1567
}
1568
if (config.getDestroyTokenAfterLogout()) {
1569
token.destroy();
1570
}
1571
return;
1572
}
1573
} catch (PKCS11Exception e) {
1574
// ignore
1575
}
1576
1577
// perform token logout
1578
Session session = null;
1579
try {
1580
session = token.getOpSession();
1581
p11.C_Logout(session.id());
1582
if (debug != null) {
1583
debug.println("logout succeeded");
1584
}
1585
} catch (PKCS11Exception pe) {
1586
if (pe.getErrorCode() == CKR_USER_NOT_LOGGED_IN) {
1587
// let this one go
1588
if (debug != null) {
1589
debug.println("user not logged in");
1590
}
1591
return;
1592
}
1593
LoginException le = new LoginException();
1594
le.initCause(pe);
1595
throw le;
1596
} finally {
1597
token.releaseSession(session);
1598
if (config.getDestroyTokenAfterLogout()) {
1599
token.destroy();
1600
}
1601
}
1602
}
1603
1604
/**
1605
* Set a <code>CallbackHandler</code>
1606
*
1607
* <p> The provider uses this handler if one is not passed to the
1608
* <code>login</code> method. The provider also uses this handler
1609
* if it invokes <code>login</code> on behalf of callers.
1610
* In either case if a handler is not set via this method,
1611
* the provider queries the
1612
* <i>auth.login.defaultCallbackHandler</i> security property
1613
* for the fully qualified class name of a default handler implementation.
1614
* If the security property is not set,
1615
* the provider is assumed to have alternative means
1616
* for obtaining authentication information.
1617
*
1618
* @param handler a <code>CallbackHandler</code> for obtaining
1619
* authentication information, which may be <code>null</code>
1620
*
1621
* @throws IllegalStateException if the provider requires configuration
1622
* and Provider.configure has not been called
1623
* @throws SecurityException if the caller does not pass a
1624
* security check for
1625
* <code>SecurityPermission("authProvider.<i>name</i>")</code>,
1626
* where <i>name</i> is the value returned by
1627
* this provider's <code>getName</code> method
1628
*/
1629
public void setCallbackHandler(CallbackHandler handler) {
1630
1631
if (!isConfigured()) {
1632
throw new IllegalStateException("Configuration is required");
1633
}
1634
1635
// security check
1636
@SuppressWarnings("removal")
1637
SecurityManager sm = System.getSecurityManager();
1638
if (sm != null) {
1639
sm.checkPermission
1640
(new SecurityPermission("authProvider." + this.getName()));
1641
}
1642
1643
synchronized (LOCK_HANDLER) {
1644
pHandler = handler;
1645
}
1646
}
1647
1648
private CallbackHandler getCallbackHandler(CallbackHandler handler) {
1649
1650
// get default handler if necessary
1651
1652
if (handler != null) {
1653
return handler;
1654
}
1655
1656
if (debug != null) {
1657
debug.println("getting provider callback handler");
1658
}
1659
1660
synchronized (LOCK_HANDLER) {
1661
// see if handler was set via setCallbackHandler
1662
if (pHandler != null) {
1663
return pHandler;
1664
}
1665
1666
try {
1667
if (debug != null) {
1668
debug.println("getting default callback handler");
1669
}
1670
1671
@SuppressWarnings("removal")
1672
CallbackHandler myHandler = AccessController.doPrivileged
1673
(new PrivilegedExceptionAction<CallbackHandler>() {
1674
public CallbackHandler run() throws Exception {
1675
1676
String defaultHandler =
1677
java.security.Security.getProperty
1678
("auth.login.defaultCallbackHandler");
1679
1680
if (defaultHandler == null ||
1681
defaultHandler.length() == 0) {
1682
1683
// ok
1684
if (debug != null) {
1685
debug.println("no default handler set");
1686
}
1687
return null;
1688
}
1689
1690
Class<?> c = Class.forName
1691
(defaultHandler,
1692
true,
1693
Thread.currentThread().getContextClassLoader());
1694
if (!javax.security.auth.callback.CallbackHandler.class.isAssignableFrom(c)) {
1695
// not the right subtype
1696
if (debug != null) {
1697
debug.println("default handler " + defaultHandler +
1698
" is not a CallbackHandler");
1699
}
1700
return null;
1701
}
1702
@SuppressWarnings("deprecation")
1703
Object result = c.newInstance();
1704
return (CallbackHandler)result;
1705
}
1706
});
1707
// save it
1708
pHandler = myHandler;
1709
return myHandler;
1710
1711
} catch (PrivilegedActionException pae) {
1712
// ok
1713
if (debug != null) {
1714
debug.println("Unable to load default callback handler");
1715
pae.printStackTrace();
1716
}
1717
}
1718
}
1719
return null;
1720
}
1721
1722
private Object writeReplace() throws ObjectStreamException {
1723
return new SunPKCS11Rep(this);
1724
}
1725
1726
/**
1727
* Serialized representation of the SunPKCS11 provider.
1728
*/
1729
private static class SunPKCS11Rep implements Serializable {
1730
1731
static final long serialVersionUID = -2896606995897745419L;
1732
1733
private final String providerName;
1734
1735
private final String configName;
1736
1737
SunPKCS11Rep(SunPKCS11 provider) throws NotSerializableException {
1738
providerName = provider.getName();
1739
configName = provider.config.getFileName();
1740
if (Security.getProvider(providerName) != provider) {
1741
throw new NotSerializableException("Only SunPKCS11 providers "
1742
+ "installed in java.security.Security can be serialized");
1743
}
1744
}
1745
1746
private Object readResolve() throws ObjectStreamException {
1747
SunPKCS11 p = (SunPKCS11)Security.getProvider(providerName);
1748
if ((p == null) || (p.config.getFileName().equals(configName) == false)) {
1749
throw new NotSerializableException("Could not find "
1750
+ providerName + " in installed providers");
1751
}
1752
return p;
1753
}
1754
}
1755
}
1756
1757