23 * questions.
24 */
25
26 package java.security;
27
28 import java.security.spec.AlgorithmParameterSpec;
29 import java.util.*;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.io.*;
32 import java.security.cert.Certificate;
33 import java.security.cert.X509Certificate;
34
35 import java.nio.ByteBuffer;
36
37 import java.security.Provider.Service;
38
39 import javax.crypto.Cipher;
40 import javax.crypto.IllegalBlockSizeException;
41 import javax.crypto.BadPaddingException;
42 import javax.crypto.NoSuchPaddingException;
43 import jdk.internal.access.JavaSecuritySignatureAccess;
44 import jdk.internal.access.SharedSecrets;
45
46 import sun.security.util.Debug;
47 import sun.security.jca.*;
48 import sun.security.jca.GetInstance.Instance;
49
50 /**
51 * The Signature class is used to provide applications the functionality
52 * of a digital signature algorithm. Digital signatures are used for
53 * authentication and integrity assurance of digital data.
54 *
55 * <p> The signature algorithm can be, among others, the NIST standard
56 * DSA, using DSA and SHA-256. The DSA algorithm using the
57 * SHA-256 message digest algorithm can be specified as {@code SHA256withDSA}.
58 * In the case of RSA the signing algorithm could be specified as, for example,
59 * {@code SHA256withRSA}.
60 * The algorithm name must be specified, as there is no default.
61 *
62 * <p> A Signature object can be used to generate and verify digital
63 * signatures.
64 *
103 * <ul>
104 * <li>{@code SHA1withDSA}</li>
105 * <li>{@code SHA256withDSA}</li>
106 * <li>{@code SHA1withRSA}</li>
107 * <li>{@code SHA256withRSA}</li>
108 * </ul>
109 * These algorithms are described in the <a href=
110 * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
111 * Signature section</a> of the
112 * Java Security Standard Algorithm Names Specification.
113 * Consult the release documentation for your implementation to see if any
114 * other algorithms are supported.
115 *
116 * @author Benjamin Renaud
117 * @since 1.1
118 *
119 */
120
121 public abstract class Signature extends SignatureSpi {
122
123 static {
124 SharedSecrets.setJavaSecuritySignatureAccess(
125 new JavaSecuritySignatureAccess() {
126 @Override
127 public void initVerify(Signature s, PublicKey publicKey,
128 AlgorithmParameterSpec params)
129 throws InvalidKeyException,
130 InvalidAlgorithmParameterException {
131 s.initVerify(publicKey, params);
132 }
133 @Override
134 public void initVerify(Signature s,
135 java.security.cert.Certificate certificate,
136 AlgorithmParameterSpec params)
137 throws InvalidKeyException,
138 InvalidAlgorithmParameterException {
139 s.initVerify(certificate, params);
140 }
141 @Override
142 public void initSign(Signature s, PrivateKey privateKey,
143 AlgorithmParameterSpec params, SecureRandom random)
144 throws InvalidKeyException,
145 InvalidAlgorithmParameterException {
146 s.initSign(privateKey, params, random);
147 }
148 });
149 }
150
151 private static final Debug debug =
152 Debug.getInstance("jca", "Signature");
153
154 private static final Debug pdebug =
155 Debug.getInstance("provider", "Provider");
156 private static final boolean skipDebug =
157 Debug.isOn("engine=") && !Debug.isOn("signature");
158
159 /*
160 * The algorithm for this signature object.
161 * This value is used to map an OID to the particular algorithm.
162 * The mapping is done in AlgorithmObject.algOID(String algorithm)
163 */
164 private String algorithm;
165
166 // The provider
167 Provider provider;
168
169 /**
170 * Possible {@link #state} value, signifying that
495 * again with a different argument, it negates the effect
496 * of this call.
497 *
498 * @param publicKey the public key of the identity whose signature is
499 * going to be verified.
500 *
501 * @exception InvalidKeyException if the key is invalid.
502 */
503 public final void initVerify(PublicKey publicKey)
504 throws InvalidKeyException {
505 engineInitVerify(publicKey);
506 state = VERIFY;
507
508 if (!skipDebug && pdebug != null) {
509 pdebug.println("Signature." + algorithm +
510 " verification algorithm from: " + getProviderName());
511 }
512 }
513
514 /**
515 * Initialize this object for verification. If this method is called
516 * again with different arguments, it negates the effect
517 * of this call.
518 *
519 * @param publicKey the public key of the identity whose signature is
520 * going to be verified.
521 * @param params the parameters used for verifying this signature.
522 *
523 * @exception InvalidKeyException if the key is invalid.
524 * @exception InvalidAlgorithmParameterException if the params is invalid.
525 */
526 final void initVerify(PublicKey publicKey, AlgorithmParameterSpec params)
527 throws InvalidKeyException, InvalidAlgorithmParameterException {
528 engineInitVerify(publicKey, params);
529 state = VERIFY;
530
531 if (!skipDebug && pdebug != null) {
532 pdebug.println("Signature." + algorithm +
533 " verification algorithm from: " + getProviderName());
534 }
535 }
536
537 private static PublicKey getPublicKeyFromCert(Certificate cert)
538 throws InvalidKeyException {
539 // If the certificate is of type X509Certificate,
540 // we should check whether it has a Key Usage
541 // extension marked as critical.
542 //if (cert instanceof java.security.cert.X509Certificate) {
543 if (cert instanceof X509Certificate) {
544 // Check whether the cert has a key usage extension
545 // marked as a critical extension.
546 // The OID for KeyUsage extension is 2.5.29.15.
547 X509Certificate c = (X509Certificate)cert;
548 Set<String> critSet = c.getCriticalExtensionOIDs();
549
550 if (critSet != null && !critSet.isEmpty()
551 && critSet.contains("2.5.29.15")) {
552 boolean[] keyUsageInfo = c.getKeyUsage();
553 // keyUsageInfo[0] is for digitalSignature.
554 if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
555 throw new InvalidKeyException("Wrong key usage");
556 }
557 }
558 return cert.getPublicKey();
559 }
560
561 /**
562 * Initializes this object for verification, using the public key from
563 * the given certificate.
564 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
565 * extension field marked as critical, and the value of the <i>key usage</i>
566 * extension field implies that the public key in
567 * the certificate and its corresponding private key are not
568 * supposed to be used for digital signatures, an
569 * {@code InvalidKeyException} is thrown.
570 *
571 * @param certificate the certificate of the identity whose signature is
572 * going to be verified.
573 *
574 * @exception InvalidKeyException if the public key in the certificate
575 * is not encoded properly or does not include required parameter
576 * information or cannot be used for digital signature purposes.
577 * @since 1.3
578 */
579 public final void initVerify(Certificate certificate)
580 throws InvalidKeyException {
581 engineInitVerify(getPublicKeyFromCert(certificate));
582 state = VERIFY;
583
584 if (!skipDebug && pdebug != null) {
585 pdebug.println("Signature." + algorithm +
586 " verification algorithm from: " + getProviderName());
587 }
588 }
589
590 /**
591 * Initializes this object for verification, using the public key from
592 * the given certificate.
593 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
594 * extension field marked as critical, and the value of the <i>key usage</i>
595 * extension field implies that the public key in
596 * the certificate and its corresponding private key are not
597 * supposed to be used for digital signatures, an
598 * {@code InvalidKeyException} is thrown.
599 *
600 * @param certificate the certificate of the identity whose signature is
601 * going to be verified.
602 * @param params the parameters used for verifying this signature.
603 *
604 * @exception InvalidKeyException if the public key in the certificate
605 * is not encoded properly or does not include required parameter
606 * information or cannot be used for digital signature purposes.
607 * @exception InvalidAlgorithmParameterException if the params is invalid.
608 *
609 * @since 13
610 */
611 final void initVerify(Certificate certificate,
612 AlgorithmParameterSpec params)
613 throws InvalidKeyException, InvalidAlgorithmParameterException {
614 engineInitVerify(getPublicKeyFromCert(certificate), params);
615 state = VERIFY;
616
617 if (!skipDebug && pdebug != null) {
618 pdebug.println("Signature." + algorithm +
619 " verification algorithm from: " + getProviderName());
620 }
621 }
622
623 /**
624 * Initialize this object for signing. If this method is called
625 * again with a different argument, it negates the effect
626 * of this call.
627 *
628 * @param privateKey the private key of the identity whose signature
629 * is going to be generated.
630 *
631 * @exception InvalidKeyException if the key is invalid.
632 */
633 public final void initSign(PrivateKey privateKey)
634 throws InvalidKeyException {
648 *
649 * @param privateKey the private key of the identity whose signature
650 * is going to be generated.
651 *
652 * @param random the source of randomness for this signature.
653 *
654 * @exception InvalidKeyException if the key is invalid.
655 */
656 public final void initSign(PrivateKey privateKey, SecureRandom random)
657 throws InvalidKeyException {
658 engineInitSign(privateKey, random);
659 state = SIGN;
660
661 if (!skipDebug && pdebug != null) {
662 pdebug.println("Signature." + algorithm +
663 " signing algorithm from: " + getProviderName());
664 }
665 }
666
667 /**
668 * Initialize this object for signing. If this method is called
669 * again with different arguments, it negates the effect
670 * of this call.
671 *
672 * @param privateKey the private key of the identity whose signature
673 * is going to be generated.
674 * @param params the parameters used for generating signature.
675 * @param random the source of randomness for this signature.
676 *
677 * @exception InvalidKeyException if the key is invalid.
678 * @exception InvalidAlgorithmParameterException if the params is invalid
679 */
680 final void initSign(PrivateKey privateKey,
681 AlgorithmParameterSpec params, SecureRandom random)
682 throws InvalidKeyException, InvalidAlgorithmParameterException {
683 engineInitSign(privateKey, params, random);
684 state = SIGN;
685
686 if (!skipDebug && pdebug != null) {
687 pdebug.println("Signature." + algorithm +
688 " signing algorithm from: " + getProviderName());
689 }
690 }
691
692 /**
693 * Returns the signature bytes of all the data updated.
694 * The format of the signature depends on the underlying
695 * signature scheme.
696 *
697 * <p>A call to this method resets this signature object to the state
698 * it was in when previously initialized for signing via a
699 * call to {@code initSign(PrivateKey)}. That is, the object is
700 * reset and available to generate another signature from the same
701 * signer, if desired, via new calls to {@code update} and
702 * {@code sign}.
703 *
704 * @return the signature bytes of the signing operation's result.
705 *
706 * @exception SignatureException if this signature object is not
707 * initialized properly or if this signature algorithm is unable to
708 * process the input data provided.
709 */
710 public final byte[] sign() throws SignatureException {
711 if (state == SIGN) {
712 return engineSign();
1208 try {
1209 sigSpi = newInstance(s);
1210 provider = s.getProvider();
1211 // not needed any more
1212 firstService = null;
1213 serviceIterator = null;
1214 return;
1215 } catch (NoSuchAlgorithmException e) {
1216 lastException = e;
1217 }
1218 }
1219 ProviderException e = new ProviderException
1220 ("Could not construct SignatureSpi instance");
1221 if (lastException != null) {
1222 e.initCause(lastException);
1223 }
1224 throw e;
1225 }
1226 }
1227
1228 // Used by engineSetParameter/engineInitSign/engineInitVerify() to
1229 // find the right provider with the supplied key, parameters, random source
1230 private void chooseProvider(int type, Key key,
1231 AlgorithmParameterSpec params, SecureRandom random)
1232 throws InvalidKeyException, InvalidAlgorithmParameterException {
1233 synchronized (lock) {
1234 if (sigSpi != null) {
1235 return;
1236 }
1237 Exception lastException = null;
1238 while ((firstService != null) || serviceIterator.hasNext()) {
1239 Service s;
1240 if (firstService != null) {
1241 s = firstService;
1242 firstService = null;
1243 } else {
1244 s = serviceIterator.next();
1245 }
1246 // if provider says it does not support this key, ignore it
1247 if (key != null && s.supportsParameter(key) == false) {
1248 continue;
1249 }
1250 // if instance is not a SignatureSpi, ignore it
1251 if (isSpi(s) == false) {
1252 continue;
1253 }
1254 try {
1255 SignatureSpi spi = newInstance(s);
1256 tryOperation(spi, type, key, params, random);
1257 provider = s.getProvider();
1258 sigSpi = spi;
1259 firstService = null;
1260 serviceIterator = null;
1261 return;
1262 } catch (Exception e) {
1263 // NoSuchAlgorithmException from newInstance()
1264 // InvalidKeyException from init()
1265 // RuntimeException (ProviderException) from init()
1266 if (lastException == null) {
1267 lastException = e;
1268 }
1269 }
1270 }
1271 // no working provider found, fail
1272 if (lastException instanceof InvalidKeyException) {
1273 throw (InvalidKeyException)lastException;
1274 }
1275 if (lastException instanceof RuntimeException) {
1276 throw (RuntimeException)lastException;
1277 }
1278 if (lastException instanceof InvalidAlgorithmParameterException) {
1279 throw (InvalidAlgorithmParameterException)lastException;
1280 }
1281
1282 String k = (key != null) ? key.getClass().getName() : "(null)";
1283 throw new InvalidKeyException
1284 ("No installed provider supports this key: "
1285 + k, lastException);
1286 }
1287 }
1288
1289 private static final int I_PUB = 1;
1290 private static final int I_PRIV = 2;
1291 private static final int I_PRIV_SR = 3;
1292 private static final int I_PUB_PARAM = 4;
1293 private static final int I_PRIV_PARAM_SR = 5;
1294 private static final int S_PARAM = 6;
1295
1296 private void tryOperation(SignatureSpi spi, int type, Key key,
1297 AlgorithmParameterSpec params, SecureRandom random)
1298 throws InvalidKeyException, InvalidAlgorithmParameterException {
1299 switch (type) {
1300 case I_PUB:
1301 spi.engineInitVerify((PublicKey)key);
1302 break;
1303 case I_PUB_PARAM:
1304 spi.engineInitVerify((PublicKey)key, params);
1305 break;
1306 case I_PRIV:
1307 spi.engineInitSign((PrivateKey)key);
1308 break;
1309 case I_PRIV_SR:
1310 spi.engineInitSign((PrivateKey)key, random);
1311 break;
1312 case I_PRIV_PARAM_SR:
1313 spi.engineInitSign((PrivateKey)key, params, random);
1314 break;
1315 case S_PARAM:
1316 spi.engineSetParameter(params);
1317 break;
1318 default:
1319 throw new AssertionError("Internal error: " + type);
1320 }
1321 }
1322
1323 protected void engineInitVerify(PublicKey publicKey)
1324 throws InvalidKeyException {
1325 if (sigSpi != null) {
1326 sigSpi.engineInitVerify(publicKey);
1327 } else {
1328 try {
1329 chooseProvider(I_PUB, publicKey, null, null);
1330 } catch (InvalidAlgorithmParameterException iape) {
1331 // should not happen, re-throw as IKE just in case
1332 throw new InvalidKeyException(iape);
1333 }
1334 }
1335 }
1336
1337 void engineInitVerify(PublicKey publicKey,
1338 AlgorithmParameterSpec params)
1339 throws InvalidKeyException, InvalidAlgorithmParameterException {
1340 if (sigSpi != null) {
1341 sigSpi.engineInitVerify(publicKey, params);
1342 } else {
1343 chooseProvider(I_PUB_PARAM, publicKey, params, null);
1344 }
1345 }
1346
1347 protected void engineInitSign(PrivateKey privateKey)
1348 throws InvalidKeyException {
1349 if (sigSpi != null) {
1350 sigSpi.engineInitSign(privateKey);
1351 } else {
1352 try {
1353 chooseProvider(I_PRIV, privateKey, null, null);
1354 } catch (InvalidAlgorithmParameterException iape) {
1355 // should not happen, re-throw as IKE just in case
1356 throw new InvalidKeyException(iape);
1357 }
1358 }
1359 }
1360
1361 protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
1362 throws InvalidKeyException {
1363 if (sigSpi != null) {
1364 sigSpi.engineInitSign(privateKey, sr);
1365 } else {
1366 try {
1367 chooseProvider(I_PRIV_SR, privateKey, null, sr);
1368 } catch (InvalidAlgorithmParameterException iape) {
1369 // should not happen, re-throw as IKE just in case
1370 throw new InvalidKeyException(iape);
1371 }
1372 }
1373 }
1374
1375 void engineInitSign(PrivateKey privateKey,
1376 AlgorithmParameterSpec params, SecureRandom sr)
1377 throws InvalidKeyException, InvalidAlgorithmParameterException {
1378 if (sigSpi != null) {
1379 sigSpi.engineInitSign(privateKey, params, sr);
1380 } else {
1381 chooseProvider(I_PRIV_PARAM_SR, privateKey, params, sr);
1382 }
1383 }
1384
1385 protected void engineUpdate(byte b) throws SignatureException {
1386 chooseFirstProvider();
1387 sigSpi.engineUpdate(b);
1388 }
1389
1390 protected void engineUpdate(byte[] b, int off, int len)
1391 throws SignatureException {
1392 chooseFirstProvider();
1393 sigSpi.engineUpdate(b, off, len);
1394 }
1395
1396 protected void engineUpdate(ByteBuffer data) {
1397 chooseFirstProvider();
1398 sigSpi.engineUpdate(data);
1399 }
1400
1401 protected byte[] engineSign() throws SignatureException {
1412 protected boolean engineVerify(byte[] sigBytes)
1413 throws SignatureException {
1414 chooseFirstProvider();
1415 return sigSpi.engineVerify(sigBytes);
1416 }
1417
1418 protected boolean engineVerify(byte[] sigBytes, int offset, int length)
1419 throws SignatureException {
1420 chooseFirstProvider();
1421 return sigSpi.engineVerify(sigBytes, offset, length);
1422 }
1423
1424 protected void engineSetParameter(String param, Object value)
1425 throws InvalidParameterException {
1426 chooseFirstProvider();
1427 sigSpi.engineSetParameter(param, value);
1428 }
1429
1430 protected void engineSetParameter(AlgorithmParameterSpec params)
1431 throws InvalidAlgorithmParameterException {
1432 if (sigSpi != null) {
1433 sigSpi.engineSetParameter(params);
1434 } else {
1435 try {
1436 chooseProvider(S_PARAM, null, params, null);
1437 } catch (InvalidKeyException ike) {
1438 // should never happen, rethrow just in case
1439 throw new InvalidAlgorithmParameterException(ike);
1440 }
1441 }
1442 }
1443
1444 protected Object engineGetParameter(String param)
1445 throws InvalidParameterException {
1446 chooseFirstProvider();
1447 return sigSpi.engineGetParameter(param);
1448 }
1449
1450 protected AlgorithmParameters engineGetParameters() {
1451 chooseFirstProvider();
1452 return sigSpi.engineGetParameters();
1453 }
1454 }
1455
1456 // adapter for RSA/ECB/PKCS1Padding ciphers
1457 @SuppressWarnings("deprecation")
1458 private static class CipherAdapter extends SignatureSpi {
1459
1460 private final Cipher cipher;
1461
|
23 * questions.
24 */
25
26 package java.security;
27
28 import java.security.spec.AlgorithmParameterSpec;
29 import java.util.*;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.io.*;
32 import java.security.cert.Certificate;
33 import java.security.cert.X509Certificate;
34
35 import java.nio.ByteBuffer;
36
37 import java.security.Provider.Service;
38
39 import javax.crypto.Cipher;
40 import javax.crypto.IllegalBlockSizeException;
41 import javax.crypto.BadPaddingException;
42 import javax.crypto.NoSuchPaddingException;
43
44 import sun.security.util.Debug;
45 import sun.security.jca.*;
46 import sun.security.jca.GetInstance.Instance;
47
48 /**
49 * The Signature class is used to provide applications the functionality
50 * of a digital signature algorithm. Digital signatures are used for
51 * authentication and integrity assurance of digital data.
52 *
53 * <p> The signature algorithm can be, among others, the NIST standard
54 * DSA, using DSA and SHA-256. The DSA algorithm using the
55 * SHA-256 message digest algorithm can be specified as {@code SHA256withDSA}.
56 * In the case of RSA the signing algorithm could be specified as, for example,
57 * {@code SHA256withRSA}.
58 * The algorithm name must be specified, as there is no default.
59 *
60 * <p> A Signature object can be used to generate and verify digital
61 * signatures.
62 *
101 * <ul>
102 * <li>{@code SHA1withDSA}</li>
103 * <li>{@code SHA256withDSA}</li>
104 * <li>{@code SHA1withRSA}</li>
105 * <li>{@code SHA256withRSA}</li>
106 * </ul>
107 * These algorithms are described in the <a href=
108 * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms">
109 * Signature section</a> of the
110 * Java Security Standard Algorithm Names Specification.
111 * Consult the release documentation for your implementation to see if any
112 * other algorithms are supported.
113 *
114 * @author Benjamin Renaud
115 * @since 1.1
116 *
117 */
118
119 public abstract class Signature extends SignatureSpi {
120
121 private static final Debug debug =
122 Debug.getInstance("jca", "Signature");
123
124 private static final Debug pdebug =
125 Debug.getInstance("provider", "Provider");
126 private static final boolean skipDebug =
127 Debug.isOn("engine=") && !Debug.isOn("signature");
128
129 /*
130 * The algorithm for this signature object.
131 * This value is used to map an OID to the particular algorithm.
132 * The mapping is done in AlgorithmObject.algOID(String algorithm)
133 */
134 private String algorithm;
135
136 // The provider
137 Provider provider;
138
139 /**
140 * Possible {@link #state} value, signifying that
465 * again with a different argument, it negates the effect
466 * of this call.
467 *
468 * @param publicKey the public key of the identity whose signature is
469 * going to be verified.
470 *
471 * @exception InvalidKeyException if the key is invalid.
472 */
473 public final void initVerify(PublicKey publicKey)
474 throws InvalidKeyException {
475 engineInitVerify(publicKey);
476 state = VERIFY;
477
478 if (!skipDebug && pdebug != null) {
479 pdebug.println("Signature." + algorithm +
480 " verification algorithm from: " + getProviderName());
481 }
482 }
483
484 /**
485 * Initializes this object for verification, using the public key from
486 * the given certificate.
487 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
488 * extension field marked as critical, and the value of the <i>key usage</i>
489 * extension field implies that the public key in
490 * the certificate and its corresponding private key are not
491 * supposed to be used for digital signatures, an
492 * {@code InvalidKeyException} is thrown.
493 *
494 * @param certificate the certificate of the identity whose signature is
495 * going to be verified.
496 *
497 * @exception InvalidKeyException if the public key in the certificate
498 * is not encoded properly or does not include required parameter
499 * information or cannot be used for digital signature purposes.
500 * @since 1.3
501 */
502 public final void initVerify(Certificate certificate)
503 throws InvalidKeyException {
504 // If the certificate is of type X509Certificate,
505 // we should check whether it has a Key Usage
506 // extension marked as critical.
507 if (certificate instanceof java.security.cert.X509Certificate) {
508 // Check whether the cert has a key usage extension
509 // marked as a critical extension.
510 // The OID for KeyUsage extension is 2.5.29.15.
511 X509Certificate cert = (X509Certificate)certificate;
512 Set<String> critSet = cert.getCriticalExtensionOIDs();
513
514 if (critSet != null && !critSet.isEmpty()
515 && critSet.contains("2.5.29.15")) {
516 boolean[] keyUsageInfo = cert.getKeyUsage();
517 // keyUsageInfo[0] is for digitalSignature.
518 if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
519 throw new InvalidKeyException("Wrong key usage");
520 }
521 }
522
523 PublicKey publicKey = certificate.getPublicKey();
524 engineInitVerify(publicKey);
525 state = VERIFY;
526
527 if (!skipDebug && pdebug != null) {
528 pdebug.println("Signature." + algorithm +
529 " verification algorithm from: " + getProviderName());
530 }
531 }
532
533 /**
534 * Initialize this object for signing. If this method is called
535 * again with a different argument, it negates the effect
536 * of this call.
537 *
538 * @param privateKey the private key of the identity whose signature
539 * is going to be generated.
540 *
541 * @exception InvalidKeyException if the key is invalid.
542 */
543 public final void initSign(PrivateKey privateKey)
544 throws InvalidKeyException {
558 *
559 * @param privateKey the private key of the identity whose signature
560 * is going to be generated.
561 *
562 * @param random the source of randomness for this signature.
563 *
564 * @exception InvalidKeyException if the key is invalid.
565 */
566 public final void initSign(PrivateKey privateKey, SecureRandom random)
567 throws InvalidKeyException {
568 engineInitSign(privateKey, random);
569 state = SIGN;
570
571 if (!skipDebug && pdebug != null) {
572 pdebug.println("Signature." + algorithm +
573 " signing algorithm from: " + getProviderName());
574 }
575 }
576
577 /**
578 * Returns the signature bytes of all the data updated.
579 * The format of the signature depends on the underlying
580 * signature scheme.
581 *
582 * <p>A call to this method resets this signature object to the state
583 * it was in when previously initialized for signing via a
584 * call to {@code initSign(PrivateKey)}. That is, the object is
585 * reset and available to generate another signature from the same
586 * signer, if desired, via new calls to {@code update} and
587 * {@code sign}.
588 *
589 * @return the signature bytes of the signing operation's result.
590 *
591 * @exception SignatureException if this signature object is not
592 * initialized properly or if this signature algorithm is unable to
593 * process the input data provided.
594 */
595 public final byte[] sign() throws SignatureException {
596 if (state == SIGN) {
597 return engineSign();
1093 try {
1094 sigSpi = newInstance(s);
1095 provider = s.getProvider();
1096 // not needed any more
1097 firstService = null;
1098 serviceIterator = null;
1099 return;
1100 } catch (NoSuchAlgorithmException e) {
1101 lastException = e;
1102 }
1103 }
1104 ProviderException e = new ProviderException
1105 ("Could not construct SignatureSpi instance");
1106 if (lastException != null) {
1107 e.initCause(lastException);
1108 }
1109 throw e;
1110 }
1111 }
1112
1113 private void chooseProvider(int type, Key key, SecureRandom random)
1114 throws InvalidKeyException {
1115 synchronized (lock) {
1116 if (sigSpi != null) {
1117 init(sigSpi, type, key, random);
1118 return;
1119 }
1120 Exception lastException = null;
1121 while ((firstService != null) || serviceIterator.hasNext()) {
1122 Service s;
1123 if (firstService != null) {
1124 s = firstService;
1125 firstService = null;
1126 } else {
1127 s = serviceIterator.next();
1128 }
1129 // if provider says it does not support this key, ignore it
1130 if (s.supportsParameter(key) == false) {
1131 continue;
1132 }
1133 // if instance is not a SignatureSpi, ignore it
1134 if (isSpi(s) == false) {
1135 continue;
1136 }
1137 try {
1138 SignatureSpi spi = newInstance(s);
1139 init(spi, type, key, random);
1140 provider = s.getProvider();
1141 sigSpi = spi;
1142 firstService = null;
1143 serviceIterator = null;
1144 return;
1145 } catch (Exception e) {
1146 // NoSuchAlgorithmException from newInstance()
1147 // InvalidKeyException from init()
1148 // RuntimeException (ProviderException) from init()
1149 if (lastException == null) {
1150 lastException = e;
1151 }
1152 }
1153 }
1154 // no working provider found, fail
1155 if (lastException instanceof InvalidKeyException) {
1156 throw (InvalidKeyException)lastException;
1157 }
1158 if (lastException instanceof RuntimeException) {
1159 throw (RuntimeException)lastException;
1160 }
1161 String k = (key != null) ? key.getClass().getName() : "(null)";
1162 throw new InvalidKeyException
1163 ("No installed provider supports this key: "
1164 + k, lastException);
1165 }
1166 }
1167
1168 private static final int I_PUB = 1;
1169 private static final int I_PRIV = 2;
1170 private static final int I_PRIV_SR = 3;
1171
1172 private void init(SignatureSpi spi, int type, Key key,
1173 SecureRandom random) throws InvalidKeyException {
1174 switch (type) {
1175 case I_PUB:
1176 spi.engineInitVerify((PublicKey)key);
1177 break;
1178 case I_PRIV:
1179 spi.engineInitSign((PrivateKey)key);
1180 break;
1181 case I_PRIV_SR:
1182 spi.engineInitSign((PrivateKey)key, random);
1183 break;
1184 default:
1185 throw new AssertionError("Internal error: " + type);
1186 }
1187 }
1188
1189 protected void engineInitVerify(PublicKey publicKey)
1190 throws InvalidKeyException {
1191 if (sigSpi != null) {
1192 sigSpi.engineInitVerify(publicKey);
1193 } else {
1194 chooseProvider(I_PUB, publicKey, null);
1195 }
1196 }
1197
1198 protected void engineInitSign(PrivateKey privateKey)
1199 throws InvalidKeyException {
1200 if (sigSpi != null) {
1201 sigSpi.engineInitSign(privateKey);
1202 } else {
1203 chooseProvider(I_PRIV, privateKey, null);
1204 }
1205 }
1206
1207 protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
1208 throws InvalidKeyException {
1209 if (sigSpi != null) {
1210 sigSpi.engineInitSign(privateKey, sr);
1211 } else {
1212 chooseProvider(I_PRIV_SR, privateKey, sr);
1213 }
1214 }
1215
1216 protected void engineUpdate(byte b) throws SignatureException {
1217 chooseFirstProvider();
1218 sigSpi.engineUpdate(b);
1219 }
1220
1221 protected void engineUpdate(byte[] b, int off, int len)
1222 throws SignatureException {
1223 chooseFirstProvider();
1224 sigSpi.engineUpdate(b, off, len);
1225 }
1226
1227 protected void engineUpdate(ByteBuffer data) {
1228 chooseFirstProvider();
1229 sigSpi.engineUpdate(data);
1230 }
1231
1232 protected byte[] engineSign() throws SignatureException {
1243 protected boolean engineVerify(byte[] sigBytes)
1244 throws SignatureException {
1245 chooseFirstProvider();
1246 return sigSpi.engineVerify(sigBytes);
1247 }
1248
1249 protected boolean engineVerify(byte[] sigBytes, int offset, int length)
1250 throws SignatureException {
1251 chooseFirstProvider();
1252 return sigSpi.engineVerify(sigBytes, offset, length);
1253 }
1254
1255 protected void engineSetParameter(String param, Object value)
1256 throws InvalidParameterException {
1257 chooseFirstProvider();
1258 sigSpi.engineSetParameter(param, value);
1259 }
1260
1261 protected void engineSetParameter(AlgorithmParameterSpec params)
1262 throws InvalidAlgorithmParameterException {
1263 chooseFirstProvider();
1264 sigSpi.engineSetParameter(params);
1265 }
1266
1267 protected Object engineGetParameter(String param)
1268 throws InvalidParameterException {
1269 chooseFirstProvider();
1270 return sigSpi.engineGetParameter(param);
1271 }
1272
1273 protected AlgorithmParameters engineGetParameters() {
1274 chooseFirstProvider();
1275 return sigSpi.engineGetParameters();
1276 }
1277 }
1278
1279 // adapter for RSA/ECB/PKCS1Padding ciphers
1280 @SuppressWarnings("deprecation")
1281 private static class CipherAdapter extends SignatureSpi {
1282
1283 private final Cipher cipher;
1284
|