Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
38919 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.IOException;
29
import java.math.BigInteger;
30
import java.nio.ByteBuffer;
31
32
import java.security.*;
33
import java.security.interfaces.*;
34
import java.security.spec.AlgorithmParameterSpec;
35
import sun.nio.ch.DirectBuffer;
36
37
import sun.security.util.*;
38
import sun.security.x509.AlgorithmId;
39
40
import sun.security.rsa.RSASignature;
41
import sun.security.rsa.RSAPadding;
42
43
import sun.security.pkcs11.wrapper.*;
44
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
45
import sun.security.util.KeyUtil;
46
47
/**
48
* Signature implementation class. This class currently supports the
49
* following algorithms:
50
*
51
* . DSA
52
* . NONEwithDSA (RawDSA)
53
* . SHA1withDSA
54
* . RSA:
55
* . MD2withRSA
56
* . MD5withRSA
57
* . SHA1withRSA
58
* . SHA224withRSA
59
* . SHA256withRSA
60
* . SHA384withRSA
61
* . SHA512withRSA
62
* . ECDSA
63
* . NONEwithECDSA
64
* . SHA1withECDSA
65
* . SHA224withECDSA
66
* . SHA256withECDSA
67
* . SHA384withECDSA
68
* . SHA512withECDSA
69
*
70
* Note that the underlying PKCS#11 token may support complete signature
71
* algorithm (e.g. CKM_DSA_SHA1, CKM_MD5_RSA_PKCS), or it may just
72
* implement the signature algorithm without hashing (e.g. CKM_DSA, CKM_PKCS),
73
* or it may only implement the raw public key operation (CKM_RSA_X_509).
74
* This class uses what is available and adds whatever extra processing
75
* is needed.
76
*
77
* @author Andreas Sterbenz
78
* @since 1.5
79
*/
80
final class P11Signature extends SignatureSpi {
81
82
// token instance
83
private final Token token;
84
85
// algorithm name
86
private final String algorithm;
87
88
// name of the key algorithm, currently either RSA or DSA
89
private final String keyAlgorithm;
90
91
// mechanism id
92
private final long mechanism;
93
94
// digest algorithm OID, if we encode RSA signature ourselves
95
private final ObjectIdentifier digestOID;
96
97
// type, one of T_* below
98
private final int type;
99
100
// key instance used, if init*() was called
101
private P11Key p11Key;
102
103
// message digest, if we do the digesting ourselves
104
private final MessageDigest md;
105
106
// associated session, if any
107
private Session session;
108
109
// mode, one of M_* below
110
private int mode;
111
112
// flag indicating whether an operation is initialized
113
private boolean initialized;
114
115
// buffer, for update(byte) or DSA
116
private final byte[] buffer;
117
118
// total number of bytes processed in current operation
119
private int bytesProcessed;
120
121
// constant for signing mode
122
private final static int M_SIGN = 1;
123
// constant for verification mode
124
private final static int M_VERIFY = 2;
125
126
// constant for type digesting, we do the hashing ourselves
127
private final static int T_DIGEST = 1;
128
// constant for type update, token does everything
129
private final static int T_UPDATE = 2;
130
// constant for type raw, used with RawDSA and NONEwithECDSA only
131
private final static int T_RAW = 3;
132
133
// XXX PKCS#11 v2.20 says "should not be longer than 1024 bits",
134
// but this is a little arbitrary
135
private final static int RAW_ECDSA_MAX = 128;
136
137
P11Signature(Token token, String algorithm, long mechanism)
138
throws NoSuchAlgorithmException, PKCS11Exception {
139
super();
140
this.token = token;
141
this.algorithm = algorithm;
142
this.mechanism = mechanism;
143
byte[] buffer = null;
144
ObjectIdentifier digestOID = null;
145
MessageDigest md = null;
146
switch ((int)mechanism) {
147
case (int)CKM_MD2_RSA_PKCS:
148
case (int)CKM_MD5_RSA_PKCS:
149
case (int)CKM_SHA1_RSA_PKCS:
150
case (int)CKM_SHA224_RSA_PKCS:
151
case (int)CKM_SHA256_RSA_PKCS:
152
case (int)CKM_SHA384_RSA_PKCS:
153
case (int)CKM_SHA512_RSA_PKCS:
154
keyAlgorithm = "RSA";
155
type = T_UPDATE;
156
buffer = new byte[1];
157
break;
158
case (int)CKM_DSA_SHA1:
159
keyAlgorithm = "DSA";
160
type = T_UPDATE;
161
buffer = new byte[1];
162
break;
163
case (int)CKM_ECDSA_SHA1:
164
keyAlgorithm = "EC";
165
type = T_UPDATE;
166
buffer = new byte[1];
167
break;
168
case (int)CKM_DSA:
169
keyAlgorithm = "DSA";
170
if (algorithm.equals("DSA")) {
171
type = T_DIGEST;
172
md = MessageDigest.getInstance("SHA-1");
173
} else if (algorithm.equals("RawDSA")) {
174
type = T_RAW;
175
buffer = new byte[20];
176
} else {
177
throw new ProviderException(algorithm);
178
}
179
break;
180
case (int)CKM_ECDSA:
181
keyAlgorithm = "EC";
182
if (algorithm.equals("NONEwithECDSA")) {
183
type = T_RAW;
184
buffer = new byte[RAW_ECDSA_MAX];
185
} else {
186
String digestAlg;
187
if (algorithm.equals("SHA1withECDSA")) {
188
digestAlg = "SHA-1";
189
} else if (algorithm.equals("SHA224withECDSA")) {
190
digestAlg = "SHA-224";
191
} else if (algorithm.equals("SHA256withECDSA")) {
192
digestAlg = "SHA-256";
193
} else if (algorithm.equals("SHA384withECDSA")) {
194
digestAlg = "SHA-384";
195
} else if (algorithm.equals("SHA512withECDSA")) {
196
digestAlg = "SHA-512";
197
} else {
198
throw new ProviderException(algorithm);
199
}
200
type = T_DIGEST;
201
md = MessageDigest.getInstance(digestAlg);
202
}
203
break;
204
case (int)CKM_RSA_PKCS:
205
case (int)CKM_RSA_X_509:
206
keyAlgorithm = "RSA";
207
type = T_DIGEST;
208
if (algorithm.equals("MD5withRSA")) {
209
md = MessageDigest.getInstance("MD5");
210
digestOID = AlgorithmId.MD5_oid;
211
} else if (algorithm.equals("SHA1withRSA")) {
212
md = MessageDigest.getInstance("SHA-1");
213
digestOID = AlgorithmId.SHA_oid;
214
} else if (algorithm.equals("MD2withRSA")) {
215
md = MessageDigest.getInstance("MD2");
216
digestOID = AlgorithmId.MD2_oid;
217
} else if (algorithm.equals("SHA224withRSA")) {
218
md = MessageDigest.getInstance("SHA-224");
219
digestOID = AlgorithmId.SHA224_oid;
220
} else if (algorithm.equals("SHA256withRSA")) {
221
md = MessageDigest.getInstance("SHA-256");
222
digestOID = AlgorithmId.SHA256_oid;
223
} else if (algorithm.equals("SHA384withRSA")) {
224
md = MessageDigest.getInstance("SHA-384");
225
digestOID = AlgorithmId.SHA384_oid;
226
} else if (algorithm.equals("SHA512withRSA")) {
227
md = MessageDigest.getInstance("SHA-512");
228
digestOID = AlgorithmId.SHA512_oid;
229
} else {
230
throw new ProviderException("Unknown signature: " + algorithm);
231
}
232
break;
233
default:
234
throw new ProviderException("Unknown mechanism: " + mechanism);
235
}
236
this.buffer = buffer;
237
this.digestOID = digestOID;
238
this.md = md;
239
}
240
241
// reset the states to the pre-initialized values
242
private void reset(boolean doCancel) {
243
244
if (!initialized) {
245
return;
246
}
247
initialized = false;
248
249
try {
250
if (session == null) {
251
return;
252
}
253
254
if (doCancel && token.explicitCancel) {
255
cancelOperation();
256
}
257
} finally {
258
p11Key.releaseKeyID();
259
session = token.releaseSession(session);
260
}
261
}
262
263
private void cancelOperation() {
264
token.ensureValid();
265
// cancel operation by finishing it; avoid killSession as some
266
// hardware vendors may require re-login
267
try {
268
if (mode == M_SIGN) {
269
if (type == T_UPDATE) {
270
token.p11.C_SignFinal(session.id(), 0);
271
} else {
272
byte[] digest;
273
if (type == T_DIGEST) {
274
digest = md.digest();
275
} else { // T_RAW
276
digest = buffer;
277
}
278
token.p11.C_Sign(session.id(), digest);
279
}
280
} else { // M_VERIFY
281
byte[] signature;
282
if (keyAlgorithm.equals("DSA")) {
283
signature = new byte[40];
284
} else {
285
signature = new byte[(p11Key.length() + 7) >> 3];
286
}
287
if (type == T_UPDATE) {
288
token.p11.C_VerifyFinal(session.id(), signature);
289
} else {
290
byte[] digest;
291
if (type == T_DIGEST) {
292
digest = md.digest();
293
} else { // T_RAW
294
digest = buffer;
295
}
296
token.p11.C_Verify(session.id(), digest, signature);
297
}
298
}
299
} catch (PKCS11Exception e) {
300
if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {
301
// Cancel Operation may be invoked after an error on a PKCS#11
302
// call. If the operation inside the token was already cancelled,
303
// do not fail here. This is part of a defensive mechanism for
304
// PKCS#11 libraries that do not strictly follow the standard.
305
return;
306
}
307
if (mode == M_VERIFY) {
308
long errorCode = e.getErrorCode();
309
if ((errorCode == CKR_SIGNATURE_INVALID) ||
310
(errorCode == CKR_SIGNATURE_LEN_RANGE)) {
311
// expected since signature is incorrect
312
return;
313
}
314
}
315
throw new ProviderException("cancel failed", e);
316
}
317
}
318
319
private void ensureInitialized() {
320
321
if (!initialized) {
322
initialize();
323
}
324
}
325
326
// assumes current state is initialized == false
327
private void initialize() {
328
329
if (p11Key == null) {
330
throw new ProviderException(
331
"Operation cannot be performed without " +
332
"calling engineInit first");
333
}
334
long keyID = p11Key.getKeyID();
335
try {
336
token.ensureValid();
337
if (session == null) {
338
session = token.getOpSession();
339
}
340
if (mode == M_SIGN) {
341
token.p11.C_SignInit(session.id(),
342
new CK_MECHANISM(mechanism), keyID);
343
} else {
344
token.p11.C_VerifyInit(session.id(),
345
new CK_MECHANISM(mechanism), keyID);
346
}
347
} catch (PKCS11Exception e) {
348
p11Key.releaseKeyID();
349
session = token.releaseSession(session);
350
throw new ProviderException("Initialization failed", e);
351
}
352
if (bytesProcessed != 0) {
353
bytesProcessed = 0;
354
if (md != null) {
355
md.reset();
356
}
357
}
358
initialized = true;
359
}
360
361
private void checkKeySize(String keyAlgo, Key key)
362
throws InvalidKeyException {
363
CK_MECHANISM_INFO mechInfo = null;
364
try {
365
mechInfo = token.getMechanismInfo(mechanism);
366
} catch (PKCS11Exception e) {
367
// should not happen, ignore for now.
368
}
369
if (mechInfo == null) {
370
// skip the check if no native info available
371
return;
372
}
373
int minKeySize = (int) mechInfo.ulMinKeySize;
374
int maxKeySize = (int) mechInfo.ulMaxKeySize;
375
// need to override the MAX keysize for SHA1withDSA
376
if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
377
maxKeySize = 1024;
378
}
379
int keySize = 0;
380
if (key instanceof P11Key) {
381
keySize = ((P11Key) key).length();
382
} else {
383
try {
384
if (keyAlgo.equals("RSA")) {
385
keySize = ((RSAKey) key).getModulus().bitLength();
386
} else if (keyAlgo.equals("DSA")) {
387
keySize = ((DSAKey) key).getParams().getP().bitLength();
388
} else if (keyAlgo.equals("EC")) {
389
keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();
390
} else {
391
throw new ProviderException("Error: unsupported algo " + keyAlgo);
392
}
393
} catch (ClassCastException cce) {
394
throw new InvalidKeyException(keyAlgo +
395
" key must be the right type", cce);
396
}
397
}
398
if ((minKeySize != -1) && (keySize < minKeySize)) {
399
throw new InvalidKeyException(keyAlgo +
400
" key must be at least " + minKeySize + " bits");
401
}
402
if ((maxKeySize != -1) && (keySize > maxKeySize)) {
403
throw new InvalidKeyException(keyAlgo +
404
" key must be at most " + maxKeySize + " bits");
405
}
406
if (keyAlgo.equals("RSA")) {
407
checkRSAKeyLength(keySize);
408
}
409
}
410
411
private void checkRSAKeyLength(int len) throws InvalidKeyException {
412
RSAPadding padding;
413
try {
414
padding = RSAPadding.getInstance
415
(RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);
416
} catch (InvalidAlgorithmParameterException iape) {
417
throw new InvalidKeyException(iape.getMessage());
418
}
419
int maxDataSize = padding.getMaxDataSize();
420
int encodedLength;
421
if (algorithm.equals("MD5withRSA") ||
422
algorithm.equals("MD2withRSA")) {
423
encodedLength = 34;
424
} else if (algorithm.equals("SHA1withRSA")) {
425
encodedLength = 35;
426
} else if (algorithm.equals("SHA224withRSA")) {
427
encodedLength = 47;
428
} else if (algorithm.equals("SHA256withRSA")) {
429
encodedLength = 51;
430
} else if (algorithm.equals("SHA384withRSA")) {
431
encodedLength = 67;
432
} else if (algorithm.equals("SHA512withRSA")) {
433
encodedLength = 83;
434
} else {
435
throw new ProviderException("Unknown signature algo: " + algorithm);
436
}
437
if (encodedLength > maxDataSize) {
438
throw new InvalidKeyException
439
("Key is too short for this signature algorithm");
440
}
441
}
442
443
// see JCA spec
444
@Override
445
protected void engineInitVerify(PublicKey publicKey)
446
throws InvalidKeyException {
447
if (publicKey == null) {
448
throw new InvalidKeyException("Key must not be null");
449
}
450
// Need to check key length whenever a new key is set
451
if (publicKey != p11Key) {
452
checkKeySize(keyAlgorithm, publicKey);
453
}
454
reset(true);
455
mode = M_VERIFY;
456
p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
457
initialize();
458
}
459
460
// see JCA spec
461
@Override
462
protected void engineInitSign(PrivateKey privateKey)
463
throws InvalidKeyException {
464
if (privateKey == null) {
465
throw new InvalidKeyException("Key must not be null");
466
}
467
// Need to check RSA key length whenever a new key is set
468
if (privateKey != p11Key) {
469
checkKeySize(keyAlgorithm, privateKey);
470
}
471
reset(true);
472
mode = M_SIGN;
473
p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
474
initialize();
475
}
476
477
// see JCA spec
478
@Override
479
protected void engineUpdate(byte b) throws SignatureException {
480
ensureInitialized();
481
switch (type) {
482
case T_UPDATE:
483
buffer[0] = b;
484
engineUpdate(buffer, 0, 1);
485
break;
486
case T_DIGEST:
487
md.update(b);
488
bytesProcessed++;
489
break;
490
case T_RAW:
491
if (bytesProcessed >= buffer.length) {
492
bytesProcessed = buffer.length + 1;
493
return;
494
}
495
buffer[bytesProcessed++] = b;
496
break;
497
default:
498
throw new ProviderException("Internal error");
499
}
500
}
501
502
// see JCA spec
503
@Override
504
protected void engineUpdate(byte[] b, int ofs, int len)
505
throws SignatureException {
506
507
ensureInitialized();
508
if (len == 0) {
509
return;
510
}
511
// check for overflow
512
if (len + bytesProcessed < 0) {
513
throw new ProviderException("Processed bytes limits exceeded.");
514
}
515
switch (type) {
516
case T_UPDATE:
517
try {
518
if (mode == M_SIGN) {
519
token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
520
} else {
521
token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
522
}
523
bytesProcessed += len;
524
} catch (PKCS11Exception e) {
525
reset(false);
526
throw new ProviderException(e);
527
}
528
break;
529
case T_DIGEST:
530
md.update(b, ofs, len);
531
bytesProcessed += len;
532
break;
533
case T_RAW:
534
if (bytesProcessed + len > buffer.length) {
535
bytesProcessed = buffer.length + 1;
536
return;
537
}
538
System.arraycopy(b, ofs, buffer, bytesProcessed, len);
539
bytesProcessed += len;
540
break;
541
default:
542
throw new ProviderException("Internal error");
543
}
544
}
545
546
// see JCA spec
547
@Override
548
protected void engineUpdate(ByteBuffer byteBuffer) {
549
550
ensureInitialized();
551
int len = byteBuffer.remaining();
552
if (len <= 0) {
553
return;
554
}
555
switch (type) {
556
case T_UPDATE:
557
if (byteBuffer instanceof DirectBuffer == false) {
558
// cannot do better than default impl
559
super.engineUpdate(byteBuffer);
560
return;
561
}
562
long addr = ((DirectBuffer)byteBuffer).address();
563
int ofs = byteBuffer.position();
564
try {
565
if (mode == M_SIGN) {
566
token.p11.C_SignUpdate
567
(session.id(), addr + ofs, null, 0, len);
568
} else {
569
token.p11.C_VerifyUpdate
570
(session.id(), addr + ofs, null, 0, len);
571
}
572
bytesProcessed += len;
573
byteBuffer.position(ofs + len);
574
} catch (PKCS11Exception e) {
575
reset(false);
576
throw new ProviderException("Update failed", e);
577
}
578
break;
579
case T_DIGEST:
580
md.update(byteBuffer);
581
bytesProcessed += len;
582
break;
583
case T_RAW:
584
if (bytesProcessed + len > buffer.length) {
585
bytesProcessed = buffer.length + 1;
586
return;
587
}
588
byteBuffer.get(buffer, bytesProcessed, len);
589
bytesProcessed += len;
590
break;
591
default:
592
reset(false);
593
throw new ProviderException("Internal error");
594
}
595
}
596
597
// see JCA spec
598
@Override
599
protected byte[] engineSign() throws SignatureException {
600
601
ensureInitialized();
602
boolean doCancel = true;
603
try {
604
byte[] signature;
605
if (type == T_UPDATE) {
606
int len = keyAlgorithm.equals("DSA") ? 40 : 0;
607
signature = token.p11.C_SignFinal(session.id(), len);
608
} else {
609
byte[] digest;
610
if (type == T_DIGEST) {
611
digest = md.digest();
612
} else { // T_RAW
613
if (mechanism == CKM_DSA) {
614
if (bytesProcessed != buffer.length) {
615
throw new SignatureException
616
("Data for RawDSA must be exactly 20 bytes long");
617
}
618
digest = buffer;
619
} else { // CKM_ECDSA
620
if (bytesProcessed > buffer.length) {
621
throw new SignatureException("Data for NONEwithECDSA"
622
+ " must be at most " + RAW_ECDSA_MAX + " bytes long");
623
}
624
digest = new byte[bytesProcessed];
625
System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
626
}
627
}
628
if (keyAlgorithm.equals("RSA") == false) {
629
// DSA and ECDSA
630
signature = token.p11.C_Sign(session.id(), digest);
631
} else { // RSA
632
byte[] data = encodeSignature(digest);
633
if (mechanism == CKM_RSA_X_509) {
634
data = pkcs1Pad(data);
635
}
636
signature = token.p11.C_Sign(session.id(), data);
637
}
638
}
639
doCancel = false;
640
641
if (keyAlgorithm.equals("RSA") == false) {
642
return dsaToASN1(signature);
643
} else {
644
return signature;
645
}
646
} catch (PKCS11Exception e) {
647
// As per the PKCS#11 standard, C_Sign and C_SignFinal may only
648
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
649
// successful calls to determine the output length. However,
650
// these cases are handled at OpenJDK's libj2pkcs11 native
651
// library. Thus, doCancel can safely be 'false' here.
652
doCancel = false;
653
throw new ProviderException(e);
654
} finally {
655
reset(doCancel);
656
}
657
}
658
659
// see JCA spec
660
@Override
661
protected boolean engineVerify(byte[] signature) throws SignatureException {
662
ensureInitialized();
663
boolean doCancel = true;
664
try {
665
if (keyAlgorithm.equals("DSA")) {
666
signature = asn1ToDSA(signature);
667
} else if (keyAlgorithm.equals("EC")) {
668
signature = asn1ToECDSA(signature);
669
}
670
if (type == T_UPDATE) {
671
token.p11.C_VerifyFinal(session.id(), signature);
672
} else {
673
byte[] digest;
674
if (type == T_DIGEST) {
675
digest = md.digest();
676
} else { // T_RAW
677
if (mechanism == CKM_DSA) {
678
if (bytesProcessed != buffer.length) {
679
throw new SignatureException
680
("Data for RawDSA must be exactly 20 bytes long");
681
}
682
digest = buffer;
683
} else {
684
if (bytesProcessed > buffer.length) {
685
throw new SignatureException("Data for NONEwithECDSA"
686
+ " must be at most " + RAW_ECDSA_MAX + " bytes long");
687
}
688
digest = new byte[bytesProcessed];
689
System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
690
}
691
}
692
if (keyAlgorithm.equals("RSA") == false) {
693
// DSA and ECDSA
694
token.p11.C_Verify(session.id(), digest, signature);
695
} else { // RSA
696
byte[] data = encodeSignature(digest);
697
if (mechanism == CKM_RSA_X_509) {
698
data = pkcs1Pad(data);
699
}
700
token.p11.C_Verify(session.id(), data, signature);
701
}
702
}
703
doCancel = false;
704
return true;
705
} catch (PKCS11Exception e) {
706
doCancel = false;
707
long errorCode = e.getErrorCode();
708
if (errorCode == CKR_SIGNATURE_INVALID) {
709
return false;
710
}
711
if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
712
// return false rather than throwing an exception
713
return false;
714
}
715
// ECF bug?
716
if (errorCode == CKR_DATA_LEN_RANGE) {
717
return false;
718
}
719
throw new ProviderException(e);
720
} finally {
721
reset(doCancel);
722
}
723
}
724
725
private byte[] pkcs1Pad(byte[] data) {
726
try {
727
int len = (p11Key.length() + 7) >> 3;
728
RSAPadding padding = RSAPadding.getInstance
729
(RSAPadding.PAD_BLOCKTYPE_1, len);
730
byte[] padded = padding.pad(data);
731
return padded;
732
} catch (GeneralSecurityException e) {
733
throw new ProviderException(e);
734
}
735
}
736
737
private byte[] encodeSignature(byte[] digest) throws SignatureException {
738
try {
739
return RSASignature.encodeSignature(digestOID, digest);
740
} catch (IOException e) {
741
throw new SignatureException("Invalid encoding", e);
742
}
743
}
744
745
// private static byte[] decodeSignature(byte[] signature) throws IOException {
746
// return RSASignature.decodeSignature(digestOID, signature);
747
// }
748
749
// For DSA and ECDSA signatures, PKCS#11 represents them as a simple
750
// byte array that contains the concatenation of r and s.
751
// For DSA, r and s are always exactly 20 bytes long.
752
// For ECDSA, r and s are of variable length, but we know that each
753
// occupies half of the array.
754
private static byte[] dsaToASN1(byte[] signature) {
755
int n = signature.length >> 1;
756
BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));
757
BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));
758
try {
759
DerOutputStream outseq = new DerOutputStream(100);
760
outseq.putInteger(r);
761
outseq.putInteger(s);
762
DerValue result = new DerValue(DerValue.tag_Sequence,
763
outseq.toByteArray());
764
return result.toByteArray();
765
} catch (java.io.IOException e) {
766
throw new RuntimeException("Internal error", e);
767
}
768
}
769
770
private static byte[] asn1ToDSA(byte[] sig) throws SignatureException {
771
try {
772
// Enforce strict DER checking for signatures
773
DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
774
DerValue[] values = in.getSequence(2);
775
776
// check number of components in the read sequence
777
// and trailing data
778
if ((values.length != 2) || (in.available() != 0)) {
779
throw new IOException("Invalid encoding for signature");
780
}
781
782
BigInteger r = values[0].getPositiveBigInteger();
783
BigInteger s = values[1].getPositiveBigInteger();
784
785
byte[] br = toByteArray(r, 20);
786
byte[] bs = toByteArray(s, 20);
787
if ((br == null) || (bs == null)) {
788
throw new SignatureException("Out of range value for R or S");
789
}
790
return P11Util.concat(br, bs);
791
} catch (SignatureException e) {
792
throw e;
793
} catch (Exception e) {
794
throw new SignatureException("Invalid encoding for signature", e);
795
}
796
}
797
798
private byte[] asn1ToECDSA(byte[] sig) throws SignatureException {
799
try {
800
// Enforce strict DER checking for signatures
801
DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
802
DerValue[] values = in.getSequence(2);
803
804
// check number of components in the read sequence
805
// and trailing data
806
if ((values.length != 2) || (in.available() != 0)) {
807
throw new IOException("Invalid encoding for signature");
808
}
809
810
BigInteger r = values[0].getPositiveBigInteger();
811
BigInteger s = values[1].getPositiveBigInteger();
812
813
// trim leading zeroes
814
byte[] br = KeyUtil.trimZeroes(r.toByteArray());
815
byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
816
int k = Math.max(br.length, bs.length);
817
// r and s each occupy half the array
818
byte[] res = new byte[k << 1];
819
System.arraycopy(br, 0, res, k - br.length, br.length);
820
System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);
821
return res;
822
} catch (Exception e) {
823
throw new SignatureException("Invalid encoding for signature", e);
824
}
825
}
826
827
private static byte[] toByteArray(BigInteger bi, int len) {
828
byte[] b = bi.toByteArray();
829
int n = b.length;
830
if (n == len) {
831
return b;
832
}
833
if ((n == len + 1) && (b[0] == 0)) {
834
byte[] t = new byte[len];
835
System.arraycopy(b, 1, t, 0, len);
836
return t;
837
}
838
if (n > len) {
839
return null;
840
}
841
// must be smaller
842
byte[] t = new byte[len];
843
System.arraycopy(b, 0, t, (len - n), n);
844
return t;
845
}
846
847
// see JCA spec
848
@Override
849
protected void engineSetParameter(String param, Object value)
850
throws InvalidParameterException {
851
throw new UnsupportedOperationException("setParameter() not supported");
852
}
853
854
// see JCA spec
855
@Override
856
protected void engineSetParameter(AlgorithmParameterSpec params)
857
throws InvalidAlgorithmParameterException {
858
if (params != null) {
859
throw new InvalidAlgorithmParameterException("No parameter accepted");
860
}
861
}
862
863
// see JCA spec
864
@Override
865
protected Object engineGetParameter(String param)
866
throws InvalidParameterException {
867
throw new UnsupportedOperationException("getParameter() not supported");
868
}
869
870
// see JCA spec
871
@Override
872
protected AlgorithmParameters engineGetParameters() {
873
return null;
874
}
875
}
876
877