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/P11PSSSignature.java
41154 views
1
/*
2
* Copyright (c) 2019, 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.ByteArrayOutputStream;
29
import java.io.IOException;
30
import java.nio.ByteBuffer;
31
import sun.nio.ch.DirectBuffer;
32
33
import java.util.Hashtable;
34
import java.util.Arrays;
35
import java.security.*;
36
import java.security.spec.AlgorithmParameterSpec;
37
import java.security.spec.MGF1ParameterSpec;
38
import java.security.spec.PSSParameterSpec;
39
import java.security.interfaces.*;
40
import sun.security.pkcs11.wrapper.*;
41
import sun.security.util.KnownOIDs;
42
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
43
import static sun.security.pkcs11.wrapper.PKCS11Exception.*;
44
45
/**
46
* RSASSA-PSS Signature implementation class. This class currently supports the
47
* following algorithms:
48
*
49
* . RSA-PSS:
50
* . RSASSA-PSS
51
* . SHA1withRSASSA-PSS
52
* . SHA224withRSASSA-PSS
53
* . SHA256withRSASSA-PSS
54
* . SHA384withRSASSA-PSS
55
* . SHA512withRSASSA-PSS
56
* . SHA3-224withRSASSA-PSS
57
* . SHA3-256withRSASSA-PSS
58
* . SHA3-384withRSASSA-PSS
59
* . SHA3-512withRSASSA-PSS
60
*
61
* Note that the underlying PKCS#11 token may support complete signature
62
* algorithm (e.g. CKM_<md>_RSA_PKCS_PSS), or it may just
63
* implement the signature algorithm without hashing (i.e. CKM_RSA_PKCS_PSS).
64
* This class uses what is available and adds whatever extra processing
65
* is needed.
66
*
67
* @since 13
68
*/
69
final class P11PSSSignature extends SignatureSpi {
70
71
private static final boolean DEBUG = false;
72
73
// mappings of digest algorithms and their output length in bytes
74
private static final Hashtable<String, Integer> DIGEST_LENGTHS =
75
new Hashtable<String, Integer>();
76
77
static {
78
DIGEST_LENGTHS.put("SHA-1", 20);
79
DIGEST_LENGTHS.put("SHA-224", 28);
80
DIGEST_LENGTHS.put("SHA-256", 32);
81
DIGEST_LENGTHS.put("SHA-384", 48);
82
DIGEST_LENGTHS.put("SHA-512", 64);
83
DIGEST_LENGTHS.put("SHA-512/224", 28);
84
DIGEST_LENGTHS.put("SHA-512/256", 32);
85
DIGEST_LENGTHS.put("SHA3-224", 28);
86
DIGEST_LENGTHS.put("SHA3-256", 32);
87
DIGEST_LENGTHS.put("SHA3-384", 48);
88
DIGEST_LENGTHS.put("SHA3-512", 64);
89
}
90
91
// utility method for looking up the std digest algorithms
92
private static String toStdName(String givenDigestAlg) {
93
if (givenDigestAlg == null) return null;
94
95
KnownOIDs given2 = KnownOIDs.findMatch(givenDigestAlg);
96
if (given2 == null) {
97
return givenDigestAlg;
98
} else {
99
return given2.stdName();
100
}
101
}
102
103
// utility method for comparing digest algorithms
104
// NOTE that first argument is assumed to be standard digest name
105
private static boolean isDigestEqual(String stdAlg, String givenAlg) {
106
if (stdAlg == null || givenAlg == null) return false;
107
108
givenAlg = toStdName(givenAlg);
109
return stdAlg.equalsIgnoreCase(givenAlg);
110
}
111
112
// token instance
113
private final Token token;
114
115
// algorithm name
116
private final String algorithm;
117
118
// name of the key algorithm, currently just RSA
119
private static final String KEY_ALGO = "RSA";
120
121
// mechanism id
122
private final CK_MECHANISM mechanism;
123
124
// type, one of T_* below
125
private final int type;
126
127
// key instance used, if init*() was called
128
private P11Key p11Key = null;
129
130
// PSS parameters and the flag controlling its access
131
private PSSParameterSpec sigParams = null;
132
private boolean isActive = false;
133
134
// message digest alg, if implied by the algorithm name
135
private final String mdAlg;
136
137
// message digest, if we do the digesting ourselves
138
private MessageDigest md = null;
139
140
// associated session, if any
141
private Session session;
142
143
// mode, one of M_* below
144
private int mode;
145
146
// flag indicating whether an operation is initialized
147
private boolean initialized = false;
148
149
// buffer, for update(byte)
150
private final byte[] buffer = new byte[1];
151
152
// total number of bytes processed in current operation
153
private int bytesProcessed = 0;
154
155
// constant for signing mode
156
private static final int M_SIGN = 1;
157
// constant for verification mode
158
private static final int M_VERIFY = 2;
159
160
// constant for type digesting, we do the hashing ourselves
161
private static final int T_DIGEST = 1;
162
// constant for type update, token does everything
163
private static final int T_UPDATE = 2;
164
165
P11PSSSignature(Token token, String algorithm, long mechId)
166
throws NoSuchAlgorithmException, PKCS11Exception {
167
super();
168
this.token = token;
169
this.algorithm = algorithm;
170
this.mechanism = new CK_MECHANISM(mechId);
171
int idx = algorithm.indexOf("with");
172
// convert to stdName
173
this.mdAlg = (idx == -1?
174
null : toStdName(algorithm.substring(0, idx)));
175
176
switch ((int)mechId) {
177
case (int)CKM_SHA1_RSA_PKCS_PSS:
178
case (int)CKM_SHA224_RSA_PKCS_PSS:
179
case (int)CKM_SHA256_RSA_PKCS_PSS:
180
case (int)CKM_SHA384_RSA_PKCS_PSS:
181
case (int)CKM_SHA512_RSA_PKCS_PSS:
182
case (int)CKM_SHA3_224_RSA_PKCS_PSS:
183
case (int)CKM_SHA3_256_RSA_PKCS_PSS:
184
case (int)CKM_SHA3_384_RSA_PKCS_PSS:
185
case (int)CKM_SHA3_512_RSA_PKCS_PSS:
186
type = T_UPDATE;
187
this.md = null;
188
break;
189
case (int)CKM_RSA_PKCS_PSS:
190
// check if the digest algo is supported by underlying PKCS11 lib
191
if (this.mdAlg != null && token.getMechanismInfo
192
(Functions.getHashMechId(this.mdAlg)) == null) {
193
throw new NoSuchAlgorithmException("Unsupported algorithm: " +
194
algorithm);
195
}
196
this.md = (this.mdAlg == null? null :
197
MessageDigest.getInstance(this.mdAlg));
198
type = T_DIGEST;
199
break;
200
default:
201
throw new ProviderException("Unsupported mechanism: " + mechId);
202
}
203
}
204
205
private static PSSParameterSpec genDefaultParams(String digestAlg,
206
P11Key key) throws SignatureException {
207
int mdLen;
208
try {
209
mdLen = DIGEST_LENGTHS.get(digestAlg);
210
} catch (NullPointerException npe) {
211
throw new SignatureException("Unsupported digest: " +
212
digestAlg);
213
}
214
int saltLen = Integer.min(mdLen, (key.length() >> 3) - mdLen -2);
215
return new PSSParameterSpec(digestAlg,
216
"MGF1", new MGF1ParameterSpec(digestAlg),
217
saltLen, PSSParameterSpec.TRAILER_FIELD_BC);
218
}
219
220
private void ensureInitialized() throws SignatureException {
221
token.ensureValid();
222
223
if (this.p11Key == null) {
224
throw new SignatureException("Missing key");
225
}
226
if (this.sigParams == null) {
227
if (this.mdAlg == null) {
228
// PSS Parameters are required for signature verification
229
throw new SignatureException
230
("Parameters required for RSASSA-PSS signature");
231
}
232
// generate default params for both sign and verify?
233
this.sigParams = genDefaultParams(this.mdAlg, this.p11Key);
234
this.mechanism.setParameter(new CK_RSA_PKCS_PSS_PARAMS(
235
this.mdAlg, "MGF1", this.mdAlg, sigParams.getSaltLength()));
236
}
237
238
if (initialized == false) {
239
try {
240
initialize();
241
} catch (ProviderException pe) {
242
throw new SignatureException(pe);
243
}
244
}
245
}
246
247
// reset the states to the pre-initialized values
248
private void reset(boolean doCancel) {
249
if (!initialized) {
250
return;
251
}
252
initialized = false;
253
254
try {
255
if (session == null) {
256
return;
257
}
258
259
if (doCancel && token.explicitCancel) {
260
cancelOperation();
261
}
262
} finally {
263
p11Key.releaseKeyID();
264
mechanism.freeHandle();
265
session = token.releaseSession(session);
266
isActive = false;
267
}
268
}
269
270
private void cancelOperation() {
271
token.ensureValid();
272
if (DEBUG) System.out.print("Cancelling operation");
273
274
// cancel operation by finishing it; avoid killSession as some
275
// hardware vendors may require re-login
276
try {
277
if (mode == M_SIGN) {
278
if (type == T_UPDATE) {
279
if (DEBUG) System.out.println(" by C_SignFinal");
280
token.p11.C_SignFinal(session.id(), 0);
281
} else {
282
byte[] digest =
283
(md == null? new byte[0] : md.digest());
284
if (DEBUG) System.out.println(" by C_Sign");
285
token.p11.C_Sign(session.id(), digest);
286
}
287
} else { // M_VERIFY
288
byte[] signature =
289
new byte[(p11Key.length() + 7) >> 3];
290
if (type == T_UPDATE) {
291
if (DEBUG) System.out.println(" by C_VerifyFinal");
292
token.p11.C_VerifyFinal(session.id(), signature);
293
} else {
294
byte[] digest =
295
(md == null? new byte[0] : md.digest());
296
if (DEBUG) System.out.println(" by C_Verify");
297
token.p11.C_Verify(session.id(), digest, signature);
298
}
299
}
300
} catch (PKCS11Exception e) {
301
if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {
302
// Cancel Operation may be invoked after an error on a PKCS#11
303
// call. If the operation inside the token was already cancelled,
304
// do not fail here. This is part of a defensive mechanism for
305
// PKCS#11 libraries that do not strictly follow the standard.
306
return;
307
}
308
if (mode == M_SIGN) {
309
throw new ProviderException("cancel failed", e);
310
}
311
// ignore failure for verification
312
}
313
}
314
315
// assumes current state is initialized == false
316
private void initialize() throws ProviderException {
317
if (DEBUG) System.out.println("Initializing");
318
319
if (p11Key == null) {
320
throw new ProviderException(
321
"No Key found, call initSign/initVerify first");
322
}
323
324
long keyID = p11Key.getKeyID();
325
try {
326
if (session == null) {
327
session = token.getOpSession();
328
}
329
if (mode == M_SIGN) {
330
token.p11.C_SignInit(session.id(), mechanism, keyID);
331
} else {
332
token.p11.C_VerifyInit(session.id(), mechanism, keyID);
333
}
334
} catch (PKCS11Exception e) {
335
p11Key.releaseKeyID();
336
session = token.releaseSession(session);
337
throw new ProviderException("Initialization failed", e);
338
}
339
if (bytesProcessed != 0) {
340
bytesProcessed = 0;
341
if (md != null) {
342
md.reset();
343
}
344
}
345
initialized = true;
346
isActive = false;
347
if (DEBUG) System.out.println("Initialized");
348
}
349
350
private void checkKeySize(Key key) throws InvalidKeyException {
351
if (DEBUG) System.out.print("Checking Key");
352
353
if (!key.getAlgorithm().equals(KEY_ALGO)) {
354
throw new InvalidKeyException("Only " + KEY_ALGO +
355
" keys are supported");
356
}
357
358
CK_MECHANISM_INFO mechInfo = null;
359
try {
360
mechInfo = token.getMechanismInfo(mechanism.mechanism);
361
} catch (PKCS11Exception e) {
362
// should not happen, ignore for now
363
if (DEBUG) {
364
System.out.println("Unexpected exception");
365
e.printStackTrace();
366
}
367
}
368
369
int keySize = 0; // in bytes
370
if (mechInfo != null) {
371
if (key instanceof P11Key) {
372
keySize = (((P11Key) key).length() + 7) >> 3;
373
} else if (key instanceof RSAKey) {
374
keySize = ((RSAKey) key).getModulus().bitLength() >> 3;
375
} else {
376
throw new InvalidKeyException("Unrecognized key type " + key);
377
}
378
// check against available native info which are in bits
379
if ((mechInfo.iMinKeySize != 0) &&
380
(keySize < (mechInfo.iMinKeySize >> 3))) {
381
throw new InvalidKeyException(KEY_ALGO +
382
" key must be at least " + mechInfo.iMinKeySize + " bits");
383
}
384
if ((mechInfo.iMaxKeySize != Integer.MAX_VALUE) &&
385
(keySize > (mechInfo.iMaxKeySize >> 3))) {
386
throw new InvalidKeyException(KEY_ALGO +
387
" key must be at most " + mechInfo.iMaxKeySize + " bits");
388
}
389
}
390
if (this.sigParams != null) {
391
String digestAlg = this.sigParams.getDigestAlgorithm();
392
int sLen = this.sigParams.getSaltLength();
393
394
int hLen = DIGEST_LENGTHS.get(toStdName(digestAlg)).intValue();
395
int minKeyLen = Math.addExact(Math.addExact(sLen, hLen), 2);
396
397
if (keySize < minKeyLen) {
398
throw new InvalidKeyException
399
("Key is too short for current params, need min " + minKeyLen);
400
}
401
}
402
}
403
404
private void setSigParams(AlgorithmParameterSpec p)
405
throws InvalidAlgorithmParameterException {
406
if (p == null) {
407
throw new InvalidAlgorithmParameterException("PSS Parameter required");
408
}
409
if (!(p instanceof PSSParameterSpec)) {
410
throw new InvalidAlgorithmParameterException
411
("Only PSSParameterSpec is supported");
412
}
413
// no need to validate again if same as current signature parameters
414
PSSParameterSpec params = (PSSParameterSpec) p;
415
if (params == this.sigParams) return;
416
417
String digestAlgorithm = params.getDigestAlgorithm();
418
if (this.mdAlg != null && !isDigestEqual(this.mdAlg, digestAlgorithm)) {
419
throw new InvalidAlgorithmParameterException
420
("Digest algorithm in Signature parameters must be " +
421
this.mdAlg);
422
}
423
424
try {
425
if (token.getMechanismInfo(Functions.getHashMechId
426
(digestAlgorithm)) == null) {
427
throw new InvalidAlgorithmParameterException
428
("Unsupported digest algorithm: " + digestAlgorithm);
429
}
430
} catch (PKCS11Exception pe) {
431
// should not happen
432
throw new InvalidAlgorithmParameterException(pe);
433
}
434
435
Integer digestLen = DIGEST_LENGTHS.get(toStdName(digestAlgorithm));
436
if (digestLen == null) {
437
throw new InvalidAlgorithmParameterException
438
("Unsupported digest algorithm in Signature parameters: " +
439
digestAlgorithm);
440
}
441
442
if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
443
throw new InvalidAlgorithmParameterException("Only supports MGF1");
444
}
445
446
// defaults to the digest algorithm unless overridden
447
String mgfDigestAlgo = digestAlgorithm;
448
AlgorithmParameterSpec mgfParams = params.getMGFParameters();
449
if (mgfParams != null) {
450
if (!(mgfParams instanceof MGF1ParameterSpec)) {
451
throw new InvalidAlgorithmParameterException
452
("Only MGF1ParameterSpec is supported");
453
}
454
mgfDigestAlgo = ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm();
455
}
456
457
if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
458
throw new InvalidAlgorithmParameterException
459
("Only supports TrailerFieldBC(1)");
460
}
461
462
int saltLen = params.getSaltLength();
463
if (this.p11Key != null) {
464
int maxSaltLen = ((this.p11Key.length() + 7) >> 3) -
465
digestLen.intValue() - 2;
466
467
if (DEBUG) {
468
System.out.println("Max saltLen = " + maxSaltLen);
469
System.out.println("Curr saltLen = " + saltLen);
470
}
471
if (maxSaltLen < 0 || saltLen > maxSaltLen) {
472
throw new InvalidAlgorithmParameterException
473
("Invalid with current key size");
474
}
475
} else if (DEBUG) {
476
System.out.println("No key available for validating saltLen");
477
}
478
479
// validated, now try to store the parameter internally
480
try {
481
this.mechanism.setParameter(
482
new CK_RSA_PKCS_PSS_PARAMS(digestAlgorithm, "MGF1",
483
mgfDigestAlgo, saltLen));
484
this.sigParams = params;
485
} catch (IllegalArgumentException iae) {
486
throw new InvalidAlgorithmParameterException(iae);
487
}
488
}
489
490
// see JCA spec
491
@Override
492
protected void engineInitVerify(PublicKey publicKey)
493
throws InvalidKeyException {
494
495
if (publicKey == null) {
496
throw new InvalidKeyException("Key must not be null");
497
}
498
499
// Need to check key length whenever a new key is set
500
if (publicKey != p11Key) {
501
checkKeySize(publicKey);
502
}
503
504
reset(true);
505
mode = M_VERIFY;
506
p11Key = P11KeyFactory.convertKey(token, publicKey, KEY_ALGO);
507
508
// attempt initialization when key and params are both available
509
if (this.p11Key != null && this.sigParams != null) {
510
try {
511
initialize();
512
} catch (ProviderException pe) {
513
throw new InvalidKeyException(pe);
514
}
515
}
516
}
517
518
// see JCA spec
519
@Override
520
protected void engineInitSign(PrivateKey privateKey)
521
throws InvalidKeyException {
522
523
if (privateKey == null) {
524
throw new InvalidKeyException("Key must not be null");
525
}
526
527
// Need to check RSA key length whenever a new key is set
528
if (privateKey != p11Key) {
529
checkKeySize(privateKey);
530
}
531
532
reset(true);
533
mode = M_SIGN;
534
p11Key = P11KeyFactory.convertKey(token, privateKey, KEY_ALGO);
535
536
// attempt initialization when key and params are both available
537
if (this.p11Key != null && this.sigParams != null) {
538
try {
539
initialize();
540
} catch (ProviderException pe) {
541
throw new InvalidKeyException(pe);
542
}
543
}
544
}
545
546
// see JCA spec
547
@Override
548
protected void engineUpdate(byte b) throws SignatureException {
549
ensureInitialized();
550
isActive = true;
551
buffer[0] = b;
552
engineUpdate(buffer, 0, 1);
553
}
554
555
// see JCA spec
556
@Override
557
protected void engineUpdate(byte[] b, int ofs, int len)
558
throws SignatureException {
559
ensureInitialized();
560
if (len == 0) {
561
return;
562
}
563
// check for overflow
564
if (len + bytesProcessed < 0) {
565
throw new ProviderException("Processed bytes limits exceeded.");
566
}
567
isActive = true;
568
switch (type) {
569
case T_UPDATE:
570
try {
571
if (mode == M_SIGN) {
572
System.out.println(this + ": Calling C_SignUpdate");
573
token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
574
} else {
575
System.out.println(this + ": Calling C_VerfifyUpdate");
576
token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
577
}
578
bytesProcessed += len;
579
} catch (PKCS11Exception e) {
580
reset(false);
581
throw new ProviderException(e);
582
}
583
break;
584
case T_DIGEST:
585
// should not happen as this should be covered by earlier checks
586
if (md == null) {
587
throw new ProviderException("PSS Parameters required");
588
}
589
md.update(b, ofs, len);
590
bytesProcessed += len;
591
break;
592
default:
593
throw new ProviderException("Internal error");
594
}
595
}
596
597
// see JCA spec
598
@Override
599
protected void engineUpdate(ByteBuffer byteBuffer) {
600
try {
601
ensureInitialized();
602
} catch (SignatureException se) {
603
throw new ProviderException(se);
604
}
605
int len = byteBuffer.remaining();
606
if (len <= 0) {
607
return;
608
}
609
isActive = true;
610
switch (type) {
611
case T_UPDATE:
612
if (byteBuffer instanceof DirectBuffer == false) {
613
// cannot do better than default impl
614
super.engineUpdate(byteBuffer);
615
return;
616
}
617
long addr = ((DirectBuffer)byteBuffer).address();
618
int ofs = byteBuffer.position();
619
try {
620
if (mode == M_SIGN) {
621
System.out.println(this + ": Calling C_SignUpdate");
622
token.p11.C_SignUpdate
623
(session.id(), addr + ofs, null, 0, len);
624
} else {
625
System.out.println(this + ": Calling C_VerifyUpdate");
626
token.p11.C_VerifyUpdate
627
(session.id(), addr + ofs, null, 0, len);
628
}
629
bytesProcessed += len;
630
byteBuffer.position(ofs + len);
631
} catch (PKCS11Exception e) {
632
reset(false);
633
throw new ProviderException("Update failed", e);
634
}
635
break;
636
case T_DIGEST:
637
// should not happen as this should be covered by earlier checks
638
if (md == null) {
639
throw new ProviderException("PSS Parameters required");
640
}
641
md.update(byteBuffer);
642
bytesProcessed += len;
643
break;
644
default:
645
reset(false);
646
throw new ProviderException("Internal error");
647
}
648
}
649
650
// see JCA spec
651
@Override
652
protected byte[] engineSign() throws SignatureException {
653
ensureInitialized();
654
boolean doCancel = true;
655
if (DEBUG) System.out.print("Generating signature");
656
try {
657
byte[] signature;
658
if (type == T_UPDATE) {
659
if (DEBUG) System.out.println(" by C_SignFinal");
660
signature = token.p11.C_SignFinal(session.id(), 0);
661
} else {
662
if (md == null) {
663
throw new ProviderException("PSS Parameters required");
664
}
665
byte[] digest = md.digest();
666
if (DEBUG) System.out.println(" by C_Sign");
667
signature = token.p11.C_Sign(session.id(), digest);
668
}
669
doCancel = false;
670
return signature;
671
} catch (PKCS11Exception pe) {
672
// As per the PKCS#11 standard, C_Sign and C_SignFinal may only
673
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
674
// successful calls to determine the output length. However,
675
// these cases are handled at OpenJDK's libj2pkcs11 native
676
// library. Thus, doCancel can safely be 'false' here.
677
doCancel = false;
678
throw new ProviderException(pe);
679
} catch (ProviderException e) {
680
throw e;
681
} finally {
682
reset(doCancel);
683
}
684
}
685
686
// see JCA spec
687
@Override
688
protected boolean engineVerify(byte[] signature) throws SignatureException {
689
ensureInitialized();
690
boolean doCancel = true;
691
if (DEBUG) System.out.print("Verifying signature");
692
try {
693
if (type == T_UPDATE) {
694
if (DEBUG) System.out.println(" by C_VerifyFinal");
695
token.p11.C_VerifyFinal(session.id(), signature);
696
} else {
697
if (md == null) {
698
throw new ProviderException("PSS Parameters required");
699
}
700
byte[] digest = md.digest();
701
if (DEBUG) System.out.println(" by C_Verify");
702
token.p11.C_Verify(session.id(), digest, signature);
703
}
704
doCancel = false;
705
return true;
706
} catch (PKCS11Exception pe) {
707
doCancel = false;
708
long errorCode = pe.getErrorCode();
709
if (errorCode == CKR_SIGNATURE_INVALID) {
710
return false;
711
}
712
if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
713
// return false rather than throwing an exception
714
return false;
715
}
716
// ECF bug?
717
if (errorCode == CKR_DATA_LEN_RANGE) {
718
return false;
719
}
720
throw new ProviderException(pe);
721
} catch (ProviderException e) {
722
throw e;
723
} finally {
724
reset(doCancel);
725
}
726
}
727
728
// see JCA spec
729
@SuppressWarnings("deprecation")
730
@Override
731
protected void engineSetParameter(String param, Object value)
732
throws InvalidParameterException {
733
throw new UnsupportedOperationException("setParameter() not supported");
734
}
735
736
// see JCA spec
737
@Override
738
protected void engineSetParameter(AlgorithmParameterSpec params)
739
throws InvalidAlgorithmParameterException {
740
// disallow changing parameters when update has been called
741
if (isActive) {
742
throw new ProviderException
743
("Cannot set parameters during operations");
744
}
745
setSigParams(params);
746
if (type == T_DIGEST) {
747
try {
748
this.md = MessageDigest.getInstance(sigParams.getDigestAlgorithm());
749
} catch (NoSuchAlgorithmException nsae) {
750
throw new InvalidAlgorithmParameterException(nsae);
751
}
752
}
753
754
// attempt initialization when key and params are both available
755
if (this.p11Key != null && this.sigParams != null) {
756
try {
757
initialize();
758
} catch (ProviderException pe) {
759
throw new InvalidAlgorithmParameterException(pe);
760
}
761
}
762
}
763
764
// see JCA spec
765
@SuppressWarnings("deprecation")
766
@Override
767
protected Object engineGetParameter(String param)
768
throws InvalidParameterException {
769
throw new UnsupportedOperationException("getParameter() not supported");
770
}
771
772
// see JCA spec
773
@Override
774
protected AlgorithmParameters engineGetParameters() {
775
if (this.sigParams != null) {
776
try {
777
AlgorithmParameters ap = AlgorithmParameters.getInstance("RSASSA-PSS");
778
ap.init(this.sigParams);
779
return ap;
780
} catch (GeneralSecurityException e) {
781
throw new RuntimeException(e);
782
}
783
}
784
return null;
785
}
786
}
787
788