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