246 md = MessageDigest.getInstance("SHA-384");
247 digestOID = AlgorithmId.SHA384_oid;
248 } else if (algorithm.equals("SHA512withRSA")) {
249 md = MessageDigest.getInstance("SHA-512");
250 digestOID = AlgorithmId.SHA512_oid;
251 } else {
252 throw new ProviderException("Unknown signature: " + algorithm);
253 }
254 break;
255 default:
256 throw new ProviderException("Unknown mechanism: " + mechanism);
257 }
258 this.buffer = buffer;
259 this.digestOID = digestOID;
260 this.md = md;
261 if (algorithm.endsWith("inP1363Format")) {
262 this.p1363Format = true;
263 }
264 }
265
266 private void ensureInitialized() {
267 token.ensureValid();
268 if (initialized == false) {
269 initialize();
270 }
271 }
272
273 private void cancelOperation() {
274 token.ensureValid();
275 if (initialized == false) {
276 return;
277 }
278 initialized = false;
279 if ((session == null) || (token.explicitCancel == false)) {
280 return;
281 }
282 if (session.hasObjects() == false) {
283 session = token.killSession(session);
284 return;
285 }
286 try {
287 // "cancel" operation by finishing it
288 // XXX make sure all this always works correctly
289 if (mode == M_SIGN) {
290 try {
291 if (type == T_UPDATE) {
292 token.p11.C_SignFinal(session.id(), 0);
293 } else {
294 byte[] digest;
295 if (type == T_DIGEST) {
296 digest = md.digest();
297 } else { // T_RAW
298 digest = buffer;
299 }
300 token.p11.C_Sign(session.id(), digest);
301 }
302 } catch (PKCS11Exception e) {
303 throw new ProviderException("cancel failed", e);
304 }
305 } else { // M_VERIFY
306 try {
307 byte[] signature;
308 if (keyAlgorithm.equals("DSA")) {
309 signature = new byte[40];
310 } else {
311 signature = new byte[(p11Key.length() + 7) >> 3];
312 }
313 if (type == T_UPDATE) {
314 token.p11.C_VerifyFinal(session.id(), signature);
315 } else {
316 byte[] digest;
317 if (type == T_DIGEST) {
318 digest = md.digest();
319 } else { // T_RAW
320 digest = buffer;
321 }
322 token.p11.C_Verify(session.id(), digest, signature);
323 }
324 } catch (PKCS11Exception e) {
325 // will fail since the signature is incorrect
326 // XXX check error code
327 }
328 }
329 } finally {
330 session = token.releaseSession(session);
331 }
332 }
333
334 // assumes current state is initialized == false
335 private void initialize() {
336 try {
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), p11Key.keyID);
343 } else {
344 token.p11.C_VerifyInit(session.id(),
345 new CK_MECHANISM(mechanism), p11Key.keyID);
346 }
347 initialized = true;
348 } catch (PKCS11Exception e) {
349 // release session when initialization failed
350 session = token.releaseSession(session);
351 throw new ProviderException("Initialization failed", e);
352 }
353 if (bytesProcessed != 0) {
354 bytesProcessed = 0;
355 if (md != null) {
356 md.reset();
357 }
358 }
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;
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 cancelOperation();
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 cancelOperation();
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 }
504 protected void engineUpdate(byte[] b, int ofs, int len)
505 throws SignatureException {
506 ensureInitialized();
507 if (len == 0) {
508 return;
509 }
510 // check for overflow
511 if (len + bytesProcessed < 0) {
512 throw new ProviderException("Processed bytes limits exceeded.");
513 }
514 switch (type) {
515 case T_UPDATE:
516 try {
517 if (mode == M_SIGN) {
518 token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
519 } else {
520 token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
521 }
522 bytesProcessed += len;
523 } catch (PKCS11Exception e) {
524 initialized = false;
525 session = token.releaseSession(session);
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
628 } else { // RSA
629 byte[] data = encodeSignature(digest);
630 if (mechanism == CKM_RSA_X_509) {
631 data = pkcs1Pad(data);
632 }
633 signature = token.p11.C_Sign(session.id(), data);
634 }
635 }
636 if (keyAlgorithm.equals("RSA")) {
637 return signature;
638 } else {
639 if (p1363Format) {
640 return signature;
641 } else {
642 return dsaToASN1(signature);
643 }
644 }
645 } catch (PKCS11Exception pe) {
646 throw new ProviderException(pe);
647 } catch (SignatureException | ProviderException e) {
648 cancelOperation();
649 throw e;
650 } finally {
651 initialized = false;
652 session = token.releaseSession(session);
653 }
654 }
655
656 // see JCA spec
657 @Override
658 protected boolean engineVerify(byte[] signature) throws SignatureException {
659 ensureInitialized();
660 try {
661 if (!p1363Format) {
662 if (keyAlgorithm.equals("DSA")) {
663 signature = asn1ToDSA(signature);
664 } else if (keyAlgorithm.equals("EC")) {
665 signature = asn1ToECDSA(signature);
666 }
667 }
668 if (type == T_UPDATE) {
669 token.p11.C_VerifyFinal(session.id(), signature);
670 } else {
671 byte[] digest;
672 if (type == T_DIGEST) {
697 }
698 token.p11.C_Verify(session.id(), data, signature);
699 }
700 }
701 return true;
702 } catch (PKCS11Exception pe) {
703 long errorCode = pe.getErrorCode();
704 if (errorCode == CKR_SIGNATURE_INVALID) {
705 return false;
706 }
707 if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
708 // return false rather than throwing an exception
709 return false;
710 }
711 // ECF bug?
712 if (errorCode == CKR_DATA_LEN_RANGE) {
713 return false;
714 }
715 throw new ProviderException(pe);
716 } catch (SignatureException | ProviderException e) {
717 cancelOperation();
718 throw e;
719 } finally {
720 initialized = false;
721 session = token.releaseSession(session);
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);
|
246 md = MessageDigest.getInstance("SHA-384");
247 digestOID = AlgorithmId.SHA384_oid;
248 } else if (algorithm.equals("SHA512withRSA")) {
249 md = MessageDigest.getInstance("SHA-512");
250 digestOID = AlgorithmId.SHA512_oid;
251 } else {
252 throw new ProviderException("Unknown signature: " + algorithm);
253 }
254 break;
255 default:
256 throw new ProviderException("Unknown mechanism: " + mechanism);
257 }
258 this.buffer = buffer;
259 this.digestOID = digestOID;
260 this.md = md;
261 if (algorithm.endsWith("inP1363Format")) {
262 this.p1363Format = true;
263 }
264 }
265
266 // reset the states to the pre-initialized values
267 private void reset(boolean doCancel) {
268 if (!initialized) {
269 return;
270 }
271 initialized = false;
272 try {
273 if (session == null) {
274 return;
275 }
276 if (doCancel && token.explicitCancel) {
277 cancelOperation();
278 }
279 } finally {
280 p11Key.decNativeKeyRef();
281 session = token.releaseSession(session);
282 }
283 }
284
285 private void cancelOperation() {
286 token.ensureValid();
287 if (session.hasObjects() == false) {
288 session = token.killSession(session);
289 return;
290 } else {
291 // "cancel" operation by finishing it
292 // XXX make sure all this always works correctly
293 try {
294 if (mode == M_SIGN) {
295 if (type == T_UPDATE) {
296 token.p11.C_SignFinal(session.id(), 0);
297 } else {
298 byte[] digest;
299 if (type == T_DIGEST) {
300 digest = md.digest();
301 } else { // T_RAW
302 digest = buffer;
303 }
304 token.p11.C_Sign(session.id(), digest);
305 }
306 } else { // M_VERIFY
307 byte[] signature;
308 if (keyAlgorithm.equals("DSA")) {
309 signature = new byte[40];
310 } else {
311 signature = new byte[(p11Key.length() + 7) >> 3];
312 }
313 if (type == T_UPDATE) {
314 token.p11.C_VerifyFinal(session.id(), signature);
315 } else {
316 byte[] digest;
317 if (type == T_DIGEST) {
318 digest = md.digest();
319 } else { // T_RAW
320 digest = buffer;
321 }
322 token.p11.C_Verify(session.id(), digest, signature);
323 }
324 }
325 } catch (PKCS11Exception e) {
326 throw new ProviderException("cancel failed", e);
327 }
328 }
329 }
330
331 // assumes current state is initialized == false
332 private void ensureInitialized() {
333 if (initialized) {
334 return;
335 }
336 if (p11Key == null) {
337 throw new ProviderException(
338 "Operation cannot be performed without " +
339 "calling engineInit first");
340 }
341 try {
342 token.ensureValid();
343 p11Key.incNativeKeyRef();
344 try {
345 if (session == null) {
346 session = token.getOpSession();
347 }
348 if (mode == M_SIGN) {
349 token.p11.C_SignInit(session.id(),
350 new CK_MECHANISM(mechanism), p11Key.keyID);
351 } else {
352 token.p11.C_VerifyInit(session.id(),
353 new CK_MECHANISM(mechanism), p11Key.keyID);
354 }
355 } catch (Throwable t) {
356 p11Key.decNativeKeyRef();
357 session = token.releaseSession(session);
358 throw t;
359 }
360 initialized = true;
361 if (bytesProcessed != 0 && md != null) {
362 md.reset();
363 }
364 bytesProcessed = 0;
365 } catch (PKCS11Exception e) {
366 throw new ProviderException("Initialization failed", e);
367 }
368 }
369
370 private void checkKeySize(String keyAlgo, Key key)
371 throws InvalidKeyException {
372 CK_MECHANISM_INFO mechInfo = null;
373 try {
374 mechInfo = token.getMechanismInfo(mechanism);
375 } catch (PKCS11Exception e) {
376 // should not happen, ignore for now.
377 }
378 if (mechInfo == null) {
379 // skip the check if no native info available
380 return;
381 }
382 int minKeySize = (int) mechInfo.ulMinKeySize;
383 int maxKeySize = (int) mechInfo.ulMaxKeySize;
384 // need to override the MAX keysize for SHA1withDSA
385 if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
386 maxKeySize = 1024;
443 } else {
444 throw new ProviderException("Unknown signature algo: " + algorithm);
445 }
446 if (encodedLength > maxDataSize) {
447 throw new InvalidKeyException
448 ("Key is too short for this signature algorithm");
449 }
450 }
451
452 // see JCA spec
453 @Override
454 protected void engineInitVerify(PublicKey publicKey)
455 throws InvalidKeyException {
456 if (publicKey == null) {
457 throw new InvalidKeyException("Key must not be null");
458 }
459 // Need to check key length whenever a new key is set
460 if (publicKey != p11Key) {
461 checkKeySize(keyAlgorithm, publicKey);
462 }
463 reset(true);
464 mode = M_VERIFY;
465 p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
466 ensureInitialized();
467 }
468
469 // see JCA spec
470 @Override
471 protected void engineInitSign(PrivateKey privateKey)
472 throws InvalidKeyException {
473 if (privateKey == null) {
474 throw new InvalidKeyException("Key must not be null");
475 }
476 // Need to check RSA key length whenever a new key is set
477 if (privateKey != p11Key) {
478 checkKeySize(keyAlgorithm, privateKey);
479 }
480 reset(true);
481 mode = M_SIGN;
482 p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
483 ensureInitialized();
484 }
485
486 // see JCA spec
487 @Override
488 protected void engineUpdate(byte b) throws SignatureException {
489 ensureInitialized();
490 switch (type) {
491 case T_UPDATE:
492 buffer[0] = b;
493 engineUpdate(buffer, 0, 1);
494 break;
495 case T_DIGEST:
496 md.update(b);
497 bytesProcessed++;
498 break;
499 case T_RAW:
500 if (bytesProcessed >= buffer.length) {
501 bytesProcessed = buffer.length + 1;
502 return;
503 }
513 protected void engineUpdate(byte[] b, int ofs, int len)
514 throws SignatureException {
515 ensureInitialized();
516 if (len == 0) {
517 return;
518 }
519 // check for overflow
520 if (len + bytesProcessed < 0) {
521 throw new ProviderException("Processed bytes limits exceeded.");
522 }
523 switch (type) {
524 case T_UPDATE:
525 try {
526 if (mode == M_SIGN) {
527 token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
528 } else {
529 token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
530 }
531 bytesProcessed += len;
532 } catch (PKCS11Exception e) {
533 reset(true);
534 throw new ProviderException(e);
535 }
536 break;
537 case T_DIGEST:
538 md.update(b, ofs, len);
539 bytesProcessed += len;
540 break;
541 case T_RAW:
542 if (bytesProcessed + len > buffer.length) {
543 bytesProcessed = buffer.length + 1;
544 return;
545 }
546 System.arraycopy(b, ofs, buffer, bytesProcessed, len);
547 bytesProcessed += len;
548 break;
549 default:
550 throw new ProviderException("Internal error");
551 }
552 }
553
636 } else { // RSA
637 byte[] data = encodeSignature(digest);
638 if (mechanism == CKM_RSA_X_509) {
639 data = pkcs1Pad(data);
640 }
641 signature = token.p11.C_Sign(session.id(), data);
642 }
643 }
644 if (keyAlgorithm.equals("RSA")) {
645 return signature;
646 } else {
647 if (p1363Format) {
648 return signature;
649 } else {
650 return dsaToASN1(signature);
651 }
652 }
653 } catch (PKCS11Exception pe) {
654 throw new ProviderException(pe);
655 } catch (SignatureException | ProviderException e) {
656 reset(true);
657 throw e;
658 } finally {
659 reset(false);
660 }
661 }
662
663 // see JCA spec
664 @Override
665 protected boolean engineVerify(byte[] signature) throws SignatureException {
666 ensureInitialized();
667 try {
668 if (!p1363Format) {
669 if (keyAlgorithm.equals("DSA")) {
670 signature = asn1ToDSA(signature);
671 } else if (keyAlgorithm.equals("EC")) {
672 signature = asn1ToECDSA(signature);
673 }
674 }
675 if (type == T_UPDATE) {
676 token.p11.C_VerifyFinal(session.id(), signature);
677 } else {
678 byte[] digest;
679 if (type == T_DIGEST) {
704 }
705 token.p11.C_Verify(session.id(), data, signature);
706 }
707 }
708 return true;
709 } catch (PKCS11Exception pe) {
710 long errorCode = pe.getErrorCode();
711 if (errorCode == CKR_SIGNATURE_INVALID) {
712 return false;
713 }
714 if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
715 // return false rather than throwing an exception
716 return false;
717 }
718 // ECF bug?
719 if (errorCode == CKR_DATA_LEN_RANGE) {
720 return false;
721 }
722 throw new ProviderException(pe);
723 } catch (SignatureException | ProviderException e) {
724 reset(true);
725 throw e;
726 } finally {
727 reset(false);
728 }
729 }
730
731 private byte[] pkcs1Pad(byte[] data) {
732 try {
733 int len = (p11Key.length() + 7) >> 3;
734 RSAPadding padding = RSAPadding.getInstance
735 (RSAPadding.PAD_BLOCKTYPE_1, len);
736 byte[] padded = padding.pad(data);
737 return padded;
738 } catch (GeneralSecurityException e) {
739 throw new ProviderException(e);
740 }
741 }
742
743 private byte[] encodeSignature(byte[] digest) throws SignatureException {
744 try {
745 return RSASignature.encodeSignature(digestOID, digest);
746 } catch (IOException e) {
747 throw new SignatureException("Invalid encoding", e);
|