< prev index next >

src/java.base/share/classes/java/security/Signature.java

Print this page




  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 


< prev index next >