1. /*
  2. * @(#)Signature.java 1.99 04/05/18
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.security;
  8. import java.security.spec.AlgorithmParameterSpec;
  9. import java.util.*;
  10. import java.util.concurrent.ConcurrentHashMap;
  11. import java.io.*;
  12. import java.security.cert.Certificate;
  13. import java.security.cert.X509Certificate;
  14. import java.nio.ByteBuffer;
  15. import java.security.Provider.Service;
  16. import javax.crypto.Cipher;
  17. import javax.crypto.CipherSpi;
  18. import javax.crypto.IllegalBlockSizeException;
  19. import javax.crypto.BadPaddingException;
  20. import javax.crypto.NoSuchPaddingException;
  21. import sun.security.util.Debug;
  22. import sun.security.jca.*;
  23. import sun.security.jca.GetInstance.Instance;
  24. /**
  25. * This Signature class is used to provide applications the functionality
  26. * of a digital signature algorithm. Digital signatures are used for
  27. * authentication and integrity assurance of digital data.
  28. *
  29. * <p> The signature algorithm can be, among others, the NIST standard
  30. * DSA, using DSA and SHA-1. The DSA algorithm using the
  31. * SHA-1 message digest algorithm can be specified as <tt>SHA1withDSA</tt>.
  32. * In the case of RSA, there are multiple choices for the message digest
  33. * algorithm, so the signing algorithm could be specified as, for example,
  34. * <tt>MD2withRSA</tt>, <tt>MD5withRSA</tt>, or <tt>SHA1withRSA</tt>.
  35. * The algorithm name must be specified, as there is no default.
  36. *
  37. * <p>Like other algorithm-based classes in Java Security, Signature
  38. * provides implementation-independent algorithms, whereby a caller
  39. * (application code) requests a particular signature algorithm
  40. * and is handed back a properly initialized Signature object. It is
  41. * also possible, if desired, to request a particular algorithm from a
  42. * particular provider. See the <code>getInstance </code> methods.
  43. *
  44. * <p>Thus, there are two ways to request a Signature algorithm object: by
  45. * specifying either just an algorithm name, or both an algorithm name
  46. * and a package provider. <ul>
  47. *
  48. * <li>If just an algorithm name is specified, the system will
  49. * determine if there is an implementation of the algorithm requested
  50. * available in the environment, and if there is more than one, if
  51. * there is a preferred one.<p>
  52. *
  53. * <li>If both an algorithm name and a package provider are specified,
  54. * the system will determine if there is an implementation of the
  55. * algorithm in the package requested, and throw an exception if there
  56. * is not.
  57. *
  58. * </ul>
  59. *
  60. * <p>A Signature object can be used to generate and verify digital
  61. * signatures.
  62. *
  63. * <p>There are three phases to the use of a Signature object for
  64. * either signing data or verifying a signature:<ol>
  65. *
  66. * <li>Initialization, with either
  67. *
  68. * <ul>
  69. *
  70. * <li>a public key, which initializes the signature for
  71. * verification (see {@link #initVerify(PublicKey) initVerify}), or
  72. *
  73. * <li>a private key (and optionally a Secure Random Number Generator),
  74. * which initializes the signature for signing
  75. * (see {@link #initSign(PrivateKey)}
  76. * and {@link #initSign(PrivateKey, SecureRandom)}).
  77. *
  78. * </ul><p>
  79. *
  80. * <li>Updating<p>
  81. *
  82. * <p>Depending on the type of initialization, this will update the
  83. * bytes to be signed or verified. See the
  84. * {@link #update(byte) update} methods.<p>
  85. *
  86. * <li>Signing or Verifying a signature on all updated bytes. See the
  87. * {@link #sign() sign} methods and the {@link #verify(byte[]) verify}
  88. * method.
  89. *
  90. * </ol>
  91. *
  92. * <p>Note that this class is abstract and extends from
  93. * <code>SignatureSpi</code> for historical reasons.
  94. * Application developers should only take notice of the methods defined in
  95. * this <code>Signature</code> class; all the methods in
  96. * the superclass are intended for cryptographic service providers who wish to
  97. * supply their own implementations of digital signature algorithms.
  98. *
  99. * @author Benjamin Renaud
  100. *
  101. * @version 1.99, 05/18/04
  102. */
  103. public abstract class Signature extends SignatureSpi {
  104. private static final Debug debug =
  105. Debug.getInstance("jca", "Signature");
  106. /*
  107. * The algorithm for this signature object.
  108. * This value is used to map an OID to the particular algorithm.
  109. * The mapping is done in AlgorithmObject.algOID(String algorithm)
  110. */
  111. private String algorithm;
  112. // The provider
  113. Provider provider;
  114. /**
  115. * Possible {@link #state} value, signifying that
  116. * this signature object has not yet been initialized.
  117. */
  118. protected final static int UNINITIALIZED = 0;
  119. /**
  120. * Possible {@link #state} value, signifying that
  121. * this signature object has been initialized for signing.
  122. */
  123. protected final static int SIGN = 2;
  124. /**
  125. * Possible {@link #state} value, signifying that
  126. * this signature object has been initialized for verification.
  127. */
  128. protected final static int VERIFY = 3;
  129. /**
  130. * Current state of this signature object.
  131. */
  132. protected int state = UNINITIALIZED;
  133. /**
  134. * Creates a Signature object for the specified algorithm.
  135. *
  136. * @param algorithm the standard string name of the algorithm.
  137. * See Appendix A in the <a href=
  138. * "../../../guide/security/CryptoSpec.html#AppA">
  139. * Java Cryptography Architecture API Specification & Reference </a>
  140. * for information about standard algorithm names.
  141. */
  142. protected Signature(String algorithm) {
  143. this.algorithm = algorithm;
  144. }
  145. // name of the special signature alg
  146. private final static String RSA_SIGNATURE = "NONEwithRSA";
  147. // name of the equivalent cipher alg
  148. private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
  149. // all the services we need to lookup for compatibility with Cipher
  150. private final static List<ServiceId> rsaIds = Arrays.asList(
  151. new ServiceId[] {
  152. new ServiceId("Signature", "NONEwithRSA"),
  153. new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"),
  154. new ServiceId("Cipher", "RSA/ECB"),
  155. new ServiceId("Cipher", "RSA//PKCS1Padding"),
  156. new ServiceId("Cipher", "RSA"),
  157. }
  158. );
  159. /**
  160. * Generates a Signature object that implements the specified digest
  161. * algorithm. If the default provider package
  162. * provides an implementation of the requested digest algorithm,
  163. * an instance of Signature containing that implementation is returned.
  164. * If the algorithm is not available in the default
  165. * package, other packages are searched.
  166. *
  167. * @param algorithm the standard name of the algorithm requested.
  168. * See Appendix A in the <a href=
  169. * "../../../guide/security/CryptoSpec.html#AppA">
  170. * Java Cryptography Architecture API Specification & Reference </a>
  171. * for information about standard algorithm names.
  172. *
  173. * @return the new Signature object.
  174. *
  175. * @exception NoSuchAlgorithmException if the algorithm is
  176. * not available in the environment.
  177. */
  178. public static Signature getInstance(String algorithm)
  179. throws NoSuchAlgorithmException {
  180. List list;
  181. if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
  182. list = GetInstance.getServices(rsaIds);
  183. } else {
  184. list = GetInstance.getServices("Signature", algorithm);
  185. }
  186. Iterator t = list.iterator();
  187. if (t.hasNext() == false) {
  188. throw new NoSuchAlgorithmException
  189. (algorithm + " Signature not available");
  190. }
  191. // try services until we find an Spi or a working Signature subclass
  192. NoSuchAlgorithmException failure;
  193. do {
  194. Service s = (Service)t.next();
  195. if (isSpi(s)) {
  196. return new Delegate(s, t, algorithm);
  197. } else {
  198. // must be a subclass of Signature, disable dynamic selection
  199. try {
  200. Instance instance =
  201. GetInstance.getInstance(s, SignatureSpi.class);
  202. return getInstance(instance, algorithm);
  203. } catch (NoSuchAlgorithmException e) {
  204. failure = e;
  205. }
  206. }
  207. } while (t.hasNext());
  208. throw failure;
  209. }
  210. private static Signature getInstance(Instance instance, String algorithm) {
  211. Signature sig;
  212. if (instance.impl instanceof Signature) {
  213. sig = (Signature)instance.impl;
  214. } else {
  215. SignatureSpi spi = (SignatureSpi)instance.impl;
  216. sig = new Delegate(spi, algorithm);
  217. }
  218. sig.provider = instance.provider;
  219. return sig;
  220. }
  221. private final static Map<String,Boolean> signatureInfo;
  222. static {
  223. signatureInfo = new ConcurrentHashMap<String,Boolean>();
  224. Boolean TRUE = Boolean.TRUE;
  225. // pre-initialize with values for our SignatureSpi implementations
  226. signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE);
  227. signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE);
  228. signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE);
  229. signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE);
  230. signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE);
  231. signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
  232. signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
  233. signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
  234. signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
  235. signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
  236. }
  237. private static boolean isSpi(Service s) {
  238. if (s.getType().equals("Cipher")) {
  239. // must be a CipherSpi, which we can wrap with the CipherAdapter
  240. return true;
  241. }
  242. String className = s.getClassName();
  243. Boolean result = signatureInfo.get(className);
  244. if (result == null) {
  245. try {
  246. Object instance = s.newInstance(null);
  247. // Signature extends SignatureSpi
  248. // so it is a "real" Spi if it is an
  249. // instance of SignatureSpi but not Signature
  250. boolean r = (instance instanceof SignatureSpi)
  251. && (instance instanceof Signature == false);
  252. if ((debug != null) && (r == false)) {
  253. debug.println("Not a SignatureSpi " + className);
  254. debug.println("Delayed provider selection may not be "
  255. + "available for algorithm " + s.getAlgorithm());
  256. }
  257. result = Boolean.valueOf(r);
  258. signatureInfo.put(className, result);
  259. } catch (Exception e) {
  260. // something is wrong, assume not an SPI
  261. return false;
  262. }
  263. }
  264. return result.booleanValue();
  265. }
  266. /**
  267. * Generates a Signature object implementing the specified
  268. * algorithm, as supplied from the specified provider, if such an
  269. * algorithm is available from the provider.
  270. *
  271. * @param algorithm the name of the algorithm requested.
  272. * See Appendix A in the <a href=
  273. * "../../../guide/security/CryptoSpec.html#AppA">
  274. * Java Cryptography Architecture API Specification & Reference </a>
  275. * for information about standard algorithm names.
  276. *
  277. * @param provider the name of the provider.
  278. *
  279. * @return the new Signature object.
  280. *
  281. * @exception NoSuchAlgorithmException if the algorithm is
  282. * not available in the package supplied by the requested
  283. * provider.
  284. *
  285. * @exception NoSuchProviderException if the provider is not
  286. * available in the environment.
  287. *
  288. * @exception IllegalArgumentException if the provider name is null
  289. * or empty.
  290. *
  291. * @see Provider
  292. */
  293. public static Signature getInstance(String algorithm, String provider)
  294. throws NoSuchAlgorithmException, NoSuchProviderException {
  295. if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
  296. // exception compatibility with existing code
  297. if ((provider == null) || (provider.length() == 0)) {
  298. throw new IllegalArgumentException("missing provider");
  299. }
  300. Provider p = Security.getProvider(provider);
  301. if (p == null) {
  302. throw new NoSuchProviderException
  303. ("no such provider: " + provider);
  304. }
  305. return getInstanceRSA(p);
  306. }
  307. Instance instance = GetInstance.getInstance
  308. ("Signature", SignatureSpi.class, algorithm, provider);
  309. return getInstance(instance, algorithm);
  310. }
  311. /**
  312. * Generates a Signature object implementing the specified
  313. * algorithm, as supplied from the specified provider, if such an
  314. * algorithm is available from the provider. Note: the
  315. * <code>provider</code> doesn't have to be registered.
  316. *
  317. * @param algorithm the name of the algorithm requested.
  318. * See Appendix A in the <a href=
  319. * "../../../guide/security/CryptoSpec.html#AppA">
  320. * Java Cryptography Architecture API Specification & Reference </a>
  321. * for information about standard algorithm names.
  322. *
  323. * @param provider the provider.
  324. *
  325. * @return the new Signature object.
  326. *
  327. * @exception NoSuchAlgorithmException if the algorithm is
  328. * not available in the package supplied by the requested
  329. * provider.
  330. *
  331. * @exception IllegalArgumentException if the <code>provider</code> is
  332. * null.
  333. *
  334. * @see Provider
  335. *
  336. * @since 1.4
  337. */
  338. public static Signature getInstance(String algorithm, Provider provider)
  339. throws NoSuchAlgorithmException {
  340. if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
  341. // exception compatibility with existing code
  342. if (provider == null) {
  343. throw new IllegalArgumentException("missing provider");
  344. }
  345. return getInstanceRSA(provider);
  346. }
  347. Instance instance = GetInstance.getInstance
  348. ("Signature", SignatureSpi.class, algorithm, provider);
  349. return getInstance(instance, algorithm);
  350. }
  351. // return an implementation for NONEwithRSA, which is a special case
  352. // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper
  353. private static Signature getInstanceRSA(Provider p)
  354. throws NoSuchAlgorithmException {
  355. // try Signature first
  356. Service s = p.getService("Signature", RSA_SIGNATURE);
  357. if (s != null) {
  358. Instance instance = GetInstance.getInstance(s, SignatureSpi.class);
  359. return getInstance(instance, RSA_SIGNATURE);
  360. }
  361. // check Cipher
  362. try {
  363. Cipher c = Cipher.getInstance(RSA_CIPHER, p);
  364. return new Delegate(new CipherAdapter(c), RSA_SIGNATURE);
  365. } catch (GeneralSecurityException e) {
  366. // throw Signature style exception message to avoid confusion,
  367. // but append Cipher exception as cause
  368. throw new NoSuchAlgorithmException("no such algorithm: "
  369. + RSA_SIGNATURE + " for provider " + p.getName(), e);
  370. }
  371. }
  372. /**
  373. * Returns the provider of this signature object.
  374. *
  375. * @return the provider of this signature object
  376. */
  377. public final Provider getProvider() {
  378. chooseFirstProvider();
  379. return this.provider;
  380. }
  381. void chooseFirstProvider() {
  382. // empty, overridden in Delegate
  383. }
  384. /**
  385. * Initializes this object for verification. If this method is called
  386. * again with a different argument, it negates the effect
  387. * of this call.
  388. *
  389. * @param publicKey the public key of the identity whose signature is
  390. * going to be verified.
  391. *
  392. * @exception InvalidKeyException if the key is invalid.
  393. */
  394. public final void initVerify(PublicKey publicKey)
  395. throws InvalidKeyException {
  396. engineInitVerify(publicKey);
  397. state = VERIFY;
  398. }
  399. /**
  400. * Initializes this object for verification, using the public key from
  401. * the given certificate.
  402. * <p>If the certificate is of type X.509 and has a <i>key usage</i>
  403. * extension field marked as critical, and the value of the <i>key usage</i>
  404. * extension field implies that the public key in
  405. * the certificate and its corresponding private key are not
  406. * supposed to be used for digital signatures, an
  407. * <code>InvalidKeyException</code> is thrown.
  408. *
  409. * @param certificate the certificate of the identity whose signature is
  410. * going to be verified.
  411. *
  412. * @exception InvalidKeyException if the public key in the certificate
  413. * is not encoded properly or does not include required parameter
  414. * information or cannot be used for digital signature purposes.
  415. */
  416. public final void initVerify(Certificate certificate)
  417. throws InvalidKeyException {
  418. // If the certificate is of type X509Certificate,
  419. // we should check whether it has a Key Usage
  420. // extension marked as critical.
  421. if (certificate instanceof java.security.cert.X509Certificate) {
  422. // Check whether the cert has a key usage extension
  423. // marked as a critical extension.
  424. // The OID for KeyUsage extension is 2.5.29.15.
  425. X509Certificate cert = (X509Certificate)certificate;
  426. Set critSet = cert.getCriticalExtensionOIDs();
  427. if (critSet != null && !critSet.isEmpty()
  428. && critSet.contains("2.5.29.15")) {
  429. boolean[] keyUsageInfo = cert.getKeyUsage();
  430. // keyUsageInfo[0] is for digitalSignature.
  431. if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
  432. throw new InvalidKeyException("Wrong key usage");
  433. }
  434. }
  435. PublicKey publicKey = certificate.getPublicKey();
  436. engineInitVerify(publicKey);
  437. state = VERIFY;
  438. }
  439. /**
  440. * Initialize this object for signing. If this method is called
  441. * again with a different argument, it negates the effect
  442. * of this call.
  443. *
  444. * @param privateKey the private key of the identity whose signature
  445. * is going to be generated.
  446. *
  447. * @exception InvalidKeyException if the key is invalid.
  448. */
  449. public final void initSign(PrivateKey privateKey)
  450. throws InvalidKeyException {
  451. engineInitSign(privateKey);
  452. state = SIGN;
  453. }
  454. /**
  455. * Initialize this object for signing. If this method is called
  456. * again with a different argument, it negates the effect
  457. * of this call.
  458. *
  459. * @param privateKey the private key of the identity whose signature
  460. * is going to be generated.
  461. *
  462. * @param random the source of randomness for this signature.
  463. *
  464. * @exception InvalidKeyException if the key is invalid.
  465. */
  466. public final void initSign(PrivateKey privateKey, SecureRandom random)
  467. throws InvalidKeyException {
  468. engineInitSign(privateKey, random);
  469. state = SIGN;
  470. }
  471. /**
  472. * Returns the signature bytes of all the data updated.
  473. * The format of the signature depends on the underlying
  474. * signature scheme.
  475. *
  476. * <p>A call to this method resets this signature object to the state
  477. * it was in when previously initialized for signing via a
  478. * call to <code>initSign(PrivateKey)</code>. That is, the object is
  479. * reset and available to generate another signature from the same
  480. * signer, if desired, via new calls to <code>update</code> and
  481. * <code>sign</code>.
  482. *
  483. * @return the signature bytes of the signing operation's result.
  484. *
  485. * @exception SignatureException if this signature object is not
  486. * initialized properly or if this signature algorithm is unable to
  487. * process the input data provided.
  488. */
  489. public final byte[] sign() throws SignatureException {
  490. if (state == SIGN) {
  491. return engineSign();
  492. }
  493. throw new SignatureException("object not initialized for " +
  494. "signing");
  495. }
  496. /**
  497. * Finishes the signature operation and stores the resulting signature
  498. * bytes in the provided buffer <code>outbuf</code>, starting at
  499. * <code>offset</code>.
  500. * The format of the signature depends on the underlying
  501. * signature scheme.
  502. *
  503. * <p>This signature object is reset to its initial state (the state it
  504. * was in after a call to one of the <code>initSign</code> methods) and
  505. * can be reused to generate further signatures with the same private key.
  506. *
  507. * @param outbuf buffer for the signature result.
  508. *
  509. * @param offset offset into <code>outbuf</code> where the signature is
  510. * stored.
  511. *
  512. * @param len number of bytes within <code>outbuf</code> allotted for the
  513. * signature.
  514. *
  515. * @return the number of bytes placed into <code>outbuf</code>.
  516. *
  517. * @exception SignatureException if this signature object is not
  518. * initialized properly, if this signature algorithm is unable to
  519. * process the input data provided, or if <code>len</code> is less
  520. * than the actual signature length.
  521. *
  522. * @since 1.2
  523. */
  524. public final int sign(byte[] outbuf, int offset, int len)
  525. throws SignatureException {
  526. if (outbuf == null) {
  527. throw new IllegalArgumentException("No output buffer given");
  528. }
  529. if (outbuf.length - offset < len) {
  530. throw new IllegalArgumentException
  531. ("Output buffer too small for specified offset and length");
  532. }
  533. if (state != SIGN) {
  534. throw new SignatureException("object not initialized for " +
  535. "signing");
  536. }
  537. return engineSign(outbuf, offset, len);
  538. }
  539. /**
  540. * Verifies the passed-in signature.
  541. *
  542. * <p>A call to this method resets this signature object to the state
  543. * it was in when previously initialized for verification via a
  544. * call to <code>initVerify(PublicKey)</code>. That is, the object is
  545. * reset and available to verify another signature from the identity
  546. * whose public key was specified in the call to <code>initVerify</code>.
  547. *
  548. * @param signature the signature bytes to be verified.
  549. *
  550. * @return true if the signature was verified, false if not.
  551. *
  552. * @exception SignatureException if this signature object is not
  553. * initialized properly, the passed-in signature is improperly
  554. * encoded or of the wrong type, if this signature algorithm is unable to
  555. * process the input data provided, etc.
  556. */
  557. public final boolean verify(byte[] signature) throws SignatureException {
  558. if (state == VERIFY) {
  559. return engineVerify(signature);
  560. }
  561. throw new SignatureException("object not initialized for " +
  562. "verification");
  563. }
  564. /**
  565. * Verifies the passed-in signature in the specified array
  566. * of bytes, starting at the specified offset.
  567. *
  568. * <p>A call to this method resets this signature object to the state
  569. * it was in when previously initialized for verification via a
  570. * call to <code>initVerify(PublicKey)</code>. That is, the object is
  571. * reset and available to verify another signature from the identity
  572. * whose public key was specified in the call to <code>initVerify</code>.
  573. *
  574. *
  575. * @param signature the signature bytes to be verified.
  576. * @param offset the offset to start from in the array of bytes.
  577. * @param length the number of bytes to use, starting at offset.
  578. *
  579. * @return true if the signature was verified, false if not.
  580. *
  581. * @exception SignatureException if this signature object is not
  582. * initialized properly, the passed-in signature is improperly
  583. * encoded or of the wrong type, if this signature algorithm is unable to
  584. * process the input data provided, etc.
  585. * @exception IllegalArgumentException if the <code>signature</code>
  586. * byte array is null, or the <code>offset</code> or <code>length</code>
  587. * is less than 0, or the sum of the <code>offset</code> and
  588. * <code>length</code> is greater than the length of the
  589. * <code>signature</code> byte array.
  590. */
  591. public final boolean verify(byte[] signature, int offset, int length)
  592. throws SignatureException {
  593. if (state == VERIFY) {
  594. if ((signature == null) || (offset < 0) || (length < 0) ||
  595. (offset + length > signature.length)) {
  596. throw new IllegalArgumentException("Bad arguments");
  597. }
  598. return engineVerify(signature, offset, length);
  599. }
  600. throw new SignatureException("object not initialized for " +
  601. "verification");
  602. }
  603. /**
  604. * Updates the data to be signed or verified by a byte.
  605. *
  606. * @param b the byte to use for the update.
  607. *
  608. * @exception SignatureException if this signature object is not
  609. * initialized properly.
  610. */
  611. public final void update(byte b) throws SignatureException {
  612. if (state == VERIFY || state == SIGN) {
  613. engineUpdate(b);
  614. } else {
  615. throw new SignatureException("object not initialized for "
  616. + "signature or verification");
  617. }
  618. }
  619. /**
  620. * Updates the data to be signed or verified, using the specified
  621. * array of bytes.
  622. *
  623. * @param data the byte array to use for the update.
  624. *
  625. * @exception SignatureException if this signature object is not
  626. * initialized properly.
  627. */
  628. public final void update(byte[] data) throws SignatureException {
  629. update(data, 0, data.length);
  630. }
  631. /**
  632. * Updates the data to be signed or verified, using the specified
  633. * array of bytes, starting at the specified offset.
  634. *
  635. * @param data the array of bytes.
  636. * @param off the offset to start from in the array of bytes.
  637. * @param len the number of bytes to use, starting at offset.
  638. *
  639. * @exception SignatureException if this signature object is not
  640. * initialized properly.
  641. */
  642. public final void update(byte[] data, int off, int len)
  643. throws SignatureException {
  644. if (state == SIGN || state == VERIFY) {
  645. engineUpdate(data, off, len);
  646. } else {
  647. throw new SignatureException("object not initialized for "
  648. + "signature or verification");
  649. }
  650. }
  651. /**
  652. * Updates the data to be signed or verified using the specified
  653. * ByteBuffer. Processes the <code>data.remaining()</code> bytes
  654. * starting at at <code>data.position()</code>.
  655. * Upon return, the buffer's position will be equal to its limit;
  656. * its limit will not have changed.
  657. *
  658. * @param data the ByteBuffer
  659. *
  660. * @exception SignatureException if this signature object is not
  661. * initialized properly.
  662. * @since 1.5
  663. */
  664. public final void update(ByteBuffer data) throws SignatureException {
  665. if ((state != SIGN) && (state != VERIFY)) {
  666. throw new SignatureException("object not initialized for "
  667. + "signature or verification");
  668. }
  669. if (data == null) {
  670. throw new NullPointerException();
  671. }
  672. engineUpdate(data);
  673. }
  674. /**
  675. * Returns the name of the algorithm for this signature object.
  676. *
  677. * @return the name of the algorithm for this signature object.
  678. */
  679. public final String getAlgorithm() {
  680. return this.algorithm;
  681. }
  682. /**
  683. * Returns a string representation of this signature object,
  684. * providing information that includes the state of the object
  685. * and the name of the algorithm used.
  686. *
  687. * @return a string representation of this signature object.
  688. */
  689. public String toString() {
  690. String initState = "";
  691. switch (state) {
  692. case UNINITIALIZED:
  693. initState = "<not initialized>";
  694. break;
  695. case VERIFY:
  696. initState = "<initialized for verifying>";
  697. break;
  698. case SIGN:
  699. initState = "<initialized for signing>";
  700. break;
  701. }
  702. return "Signature object: " + getAlgorithm() + initState;
  703. }
  704. /**
  705. * Sets the specified algorithm parameter to the specified value.
  706. * This method supplies a general-purpose mechanism through
  707. * which it is possible to set the various parameters of this object.
  708. * A parameter may be any settable parameter for the algorithm, such as
  709. * a parameter size, or a source of random bits for signature generation
  710. * (if appropriate), or an indication of whether or not to perform
  711. * a specific but optional computation. A uniform algorithm-specific
  712. * naming scheme for each parameter is desirable but left unspecified
  713. * at this time.
  714. *
  715. * @param param the string identifier of the parameter.
  716. * @param value the parameter value.
  717. *
  718. * @exception InvalidParameterException if <code>param</code> is an
  719. * invalid parameter for this signature algorithm engine,
  720. * the parameter is already set
  721. * and cannot be set again, a security exception occurs, and so on.
  722. *
  723. * @see #getParameter
  724. *
  725. * @deprecated Use
  726. * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
  727. * setParameter}.
  728. */
  729. @Deprecated
  730. public final void setParameter(String param, Object value)
  731. throws InvalidParameterException {
  732. engineSetParameter(param, value);
  733. }
  734. /**
  735. * Initializes this signature engine with the specified parameter set.
  736. *
  737. * @param params the parameters
  738. *
  739. * @exception InvalidAlgorithmParameterException if the given parameters
  740. * are inappropriate for this signature engine
  741. *
  742. * @see #getParameters
  743. */
  744. public final void setParameter(AlgorithmParameterSpec params)
  745. throws InvalidAlgorithmParameterException {
  746. engineSetParameter(params);
  747. }
  748. /**
  749. * Returns the parameters used with this signature object.
  750. *
  751. * <p>The returned parameters may be the same that were used to initialize
  752. * this signature, or may contain a combination of default and randomly
  753. * generated parameter values used by the underlying signature
  754. * implementation if this signature requires algorithm parameters but
  755. * was not initialized with any.
  756. *
  757. * @return the parameters used with this signature, or null if this
  758. * signature does not use any parameters.
  759. *
  760. * @see #setParameter(AlgorithmParameterSpec)
  761. */
  762. public final AlgorithmParameters getParameters() {
  763. return engineGetParameters();
  764. }
  765. /**
  766. * Gets the value of the specified algorithm parameter. This method
  767. * supplies a general-purpose mechanism through which it is possible to
  768. * get the various parameters of this object. A parameter may be any
  769. * settable parameter for the algorithm, such as a parameter size, or
  770. * a source of random bits for signature generation (if appropriate),
  771. * or an indication of whether or not to perform a specific but optional
  772. * computation. A uniform algorithm-specific naming scheme for each
  773. * parameter is desirable but left unspecified at this time.
  774. *
  775. * @param param the string name of the parameter.
  776. *
  777. * @return the object that represents the parameter value, or null if
  778. * there is none.
  779. *
  780. * @exception InvalidParameterException if <code>param</code> is an invalid
  781. * parameter for this engine, or another exception occurs while
  782. * trying to get this parameter.
  783. *
  784. * @see #setParameter(String, Object)
  785. *
  786. * @deprecated
  787. */
  788. @Deprecated
  789. public final Object getParameter(String param)
  790. throws InvalidParameterException {
  791. return engineGetParameter(param);
  792. }
  793. /**
  794. * Returns a clone if the implementation is cloneable.
  795. *
  796. * @return a clone if the implementation is cloneable.
  797. *
  798. * @exception CloneNotSupportedException if this is called
  799. * on an implementation that does not support <code>Cloneable</code>.
  800. */
  801. public Object clone() throws CloneNotSupportedException {
  802. if (this instanceof Cloneable) {
  803. return super.clone();
  804. } else {
  805. throw new CloneNotSupportedException();
  806. }
  807. }
  808. /*
  809. * The following class allows providers to extend from SignatureSpi
  810. * rather than from Signature. It represents a Signature with an
  811. * encapsulated, provider-supplied SPI object (of type SignatureSpi).
  812. * If the provider implementation is an instance of SignatureSpi, the
  813. * getInstance() methods above return an instance of this class, with
  814. * the SPI object encapsulated.
  815. *
  816. * Note: All SPI methods from the original Signature class have been
  817. * moved up the hierarchy into a new class (SignatureSpi), which has
  818. * been interposed in the hierarchy between the API (Signature)
  819. * and its original parent (Object).
  820. */
  821. private static class Delegate extends Signature {
  822. // The provider implementation (delegate)
  823. // filled in once the provider is selected
  824. private SignatureSpi sigSpi;
  825. // lock for mutex during provider selection
  826. private final Object lock;
  827. // next service to try in provider selection
  828. // null once provider is selected
  829. private Service firstService;
  830. // remaining services to try in provider selection
  831. // null once provider is selected
  832. private Iterator serviceIterator;
  833. // constructor
  834. Delegate(SignatureSpi sigSpi, String algorithm) {
  835. super(algorithm);
  836. this.sigSpi = sigSpi;
  837. this.lock = null; // no lock needed
  838. }
  839. // used with delayed provider selection
  840. Delegate(Service service, Iterator iterator, String algorithm) {
  841. super(algorithm);
  842. this.firstService = service;
  843. this.serviceIterator = iterator;
  844. this.lock = new Object();
  845. }
  846. /*
  847. * Returns a clone if the delegate is cloneable.
  848. *
  849. * @return a clone if the delegate is cloneable.
  850. *
  851. * @exception CloneNotSupportedException if this is called on a
  852. * delegate that does not support <code>Cloneable</code>.
  853. */
  854. public Object clone() throws CloneNotSupportedException {
  855. chooseFirstProvider();
  856. if (sigSpi instanceof Cloneable) {
  857. SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
  858. // Because 'algorithm' and 'provider' are private
  859. // members of our supertype, we must perform a cast to
  860. // access them.
  861. Signature that =
  862. new Delegate(sigSpiClone, ((Signature)this).algorithm);
  863. that.provider = ((Signature)this).provider;
  864. return that;
  865. } else {
  866. throw new CloneNotSupportedException();
  867. }
  868. }
  869. private static SignatureSpi newInstance(Service s)
  870. throws NoSuchAlgorithmException {
  871. if (s.getType().equals("Cipher")) {
  872. // must be NONEwithRSA
  873. try {
  874. Cipher c = Cipher.getInstance(RSA_CIPHER, s.getProvider());
  875. return new CipherAdapter(c);
  876. } catch (NoSuchPaddingException e) {
  877. throw new NoSuchAlgorithmException(e);
  878. }
  879. } else {
  880. Object o = s.newInstance(null);
  881. if (o instanceof SignatureSpi == false) {
  882. throw new NoSuchAlgorithmException
  883. ("Not a SignatureSpi: " + o.getClass().getName());
  884. }
  885. return (SignatureSpi)o;
  886. }
  887. }
  888. // max number of debug warnings to print from chooseFirstProvider()
  889. private static int warnCount = 10;
  890. /**
  891. * Choose the Spi from the first provider available. Used if
  892. * delayed provider selection is not possible because initSign()/
  893. * initVerify() is not the first method called.
  894. */
  895. void chooseFirstProvider() {
  896. if (sigSpi != null) {
  897. return;
  898. }
  899. synchronized (lock) {
  900. if (sigSpi != null) {
  901. return;
  902. }
  903. if (debug != null) {
  904. int w = --warnCount;
  905. if (w >= 0) {
  906. debug.println("Signature.init() not first method "
  907. + "called, disabling delayed provider selection");
  908. if (w == 0) {
  909. debug.println("Further warnings of this type will "
  910. + "be suppressed");
  911. }
  912. new Exception("Call trace").printStackTrace();
  913. }
  914. }
  915. Exception lastException = null;
  916. while ((firstService != null) || serviceIterator.hasNext()) {
  917. Service s;
  918. if (firstService != null) {
  919. s = firstService;
  920. firstService = null;
  921. } else {
  922. s = (Service)serviceIterator.next();
  923. }
  924. if (isSpi(s) == false) {
  925. continue;
  926. }
  927. try {
  928. sigSpi = newInstance(s);
  929. provider = s.getProvider();
  930. // not needed any more
  931. firstService = null;
  932. serviceIterator = null;
  933. return;
  934. } catch (NoSuchAlgorithmException e) {
  935. lastException = e;
  936. }
  937. }
  938. ProviderException e = new ProviderException
  939. ("Could not construct SignatureSpi instance");
  940. if (lastException != null) {
  941. e.initCause(lastException);
  942. }
  943. throw e;
  944. }
  945. }
  946. private void chooseProvider(int type, Key key, SecureRandom random)
  947. throws InvalidKeyException {
  948. synchronized (lock) {
  949. if (sigSpi != null) {
  950. init(sigSpi, type, key, random);
  951. return;
  952. }
  953. Exception lastException = null;
  954. while ((firstService != null) || serviceIterator.hasNext()) {
  955. Service s;
  956. if (firstService != null) {
  957. s = firstService;
  958. firstService = null;
  959. } else {
  960. s = (Service)serviceIterator.next();
  961. }
  962. // if provider says it does not support this key, ignore it
  963. if (s.supportsParameter(key) == false) {
  964. continue;
  965. }
  966. // if instance is not a SignatureSpi, ignore it
  967. if (isSpi(s) == false) {
  968. continue;
  969. }
  970. try {
  971. SignatureSpi spi = newInstance(s);
  972. init(spi, type, key, random);
  973. provider = s.getProvider();
  974. sigSpi = spi;
  975. firstService = null;
  976. serviceIterator = null;
  977. return;
  978. } catch (Exception e) {
  979. // NoSuchAlgorithmException from newInstance()
  980. // InvalidKeyException from init()
  981. // RuntimeException (ProviderException) from init()
  982. if (lastException == null) {
  983. lastException = e;
  984. }
  985. }
  986. }
  987. // no working provider found, fail
  988. if (lastException instanceof InvalidKeyException) {
  989. throw (InvalidKeyException)lastException;
  990. }
  991. if (lastException instanceof RuntimeException) {
  992. throw (RuntimeException)lastException;
  993. }
  994. String k = (key != null) ? key.getClass().getName() : "(null)";
  995. throw new InvalidKeyException
  996. ("No installed provider supports this key: "
  997. + k, lastException);
  998. }
  999. }
  1000. private final static int I_PUB = 1;
  1001. private final static int I_PRIV = 2;
  1002. private final static int I_PRIV_SR = 3;
  1003. private void init(SignatureSpi spi, int type, Key key,
  1004. SecureRandom random) throws InvalidKeyException {
  1005. switch (type) {
  1006. case I_PUB:
  1007. spi.engineInitVerify((PublicKey)key);
  1008. break;
  1009. case I_PRIV:
  1010. spi.engineInitSign((PrivateKey)key);
  1011. break;
  1012. case I_PRIV_SR:
  1013. spi.engineInitSign((PrivateKey)key, random);
  1014. break;
  1015. default:
  1016. throw new AssertionError("Internal error: " + type);
  1017. }
  1018. }
  1019. protected void engineInitVerify(PublicKey publicKey)
  1020. throws InvalidKeyException {
  1021. if (sigSpi != null) {
  1022. sigSpi.engineInitVerify(publicKey);
  1023. } else {
  1024. chooseProvider(I_PUB, publicKey, null);
  1025. }
  1026. }
  1027. protected void engineInitSign(PrivateKey privateKey)
  1028. throws InvalidKeyException {
  1029. if (sigSpi != null) {
  1030. sigSpi.engineInitSign(privateKey);
  1031. } else {
  1032. chooseProvider(I_PRIV, privateKey, null);
  1033. }
  1034. }
  1035. protected void engineInitSign(PrivateKey privateKey, SecureRandom sr)
  1036. throws InvalidKeyException {
  1037. if (sigSpi != null) {
  1038. sigSpi.engineInitSign(privateKey, sr);
  1039. } else {
  1040. chooseProvider(I_PRIV_SR, privateKey, sr);
  1041. }
  1042. }
  1043. protected void engineUpdate(byte b) throws SignatureException {
  1044. chooseFirstProvider();
  1045. sigSpi.engineUpdate(b);
  1046. }
  1047. protected void engineUpdate(byte[] b, int off, int len)
  1048. throws SignatureException {
  1049. chooseFirstProvider();
  1050. sigSpi.engineUpdate(b, off, len);
  1051. }
  1052. protected void engineUpdate(ByteBuffer data) {
  1053. chooseFirstProvider();
  1054. sigSpi.engineUpdate(data);
  1055. }
  1056. protected byte[] engineSign() throws SignatureException {
  1057. chooseFirstProvider();
  1058. return sigSpi.engineSign();
  1059. }
  1060. protected int engineSign(byte[] outbuf, int offset, int len)
  1061. throws SignatureException {
  1062. chooseFirstProvider();
  1063. return sigSpi.engineSign(outbuf, offset, len);
  1064. }
  1065. protected boolean engineVerify(byte[] sigBytes)
  1066. throws SignatureException {
  1067. chooseFirstProvider();
  1068. return sigSpi.engineVerify(sigBytes);
  1069. }
  1070. protected boolean engineVerify(byte[] sigBytes, int offset, int length)
  1071. throws SignatureException {
  1072. chooseFirstProvider();
  1073. return sigSpi.engineVerify(sigBytes, offset, length);
  1074. }
  1075. protected void engineSetParameter(String param, Object value)
  1076. throws InvalidParameterException {
  1077. chooseFirstProvider();
  1078. sigSpi.engineSetParameter(param, value);
  1079. }
  1080. protected void engineSetParameter(AlgorithmParameterSpec params)
  1081. throws InvalidAlgorithmParameterException {
  1082. chooseFirstProvider();
  1083. sigSpi.engineSetParameter(params);
  1084. }
  1085. protected Object engineGetParameter(String param)
  1086. throws InvalidParameterException {
  1087. chooseFirstProvider();
  1088. return sigSpi.engineGetParameter(param);
  1089. }
  1090. protected AlgorithmParameters engineGetParameters() {
  1091. chooseFirstProvider();
  1092. return sigSpi.engineGetParameters();
  1093. }
  1094. }
  1095. // adapter for RSA/ECB/PKCS1Padding ciphers
  1096. private static class CipherAdapter extends SignatureSpi {
  1097. private final Cipher cipher;
  1098. private ByteArrayOutputStream data;
  1099. CipherAdapter(Cipher cipher) {
  1100. this.cipher = cipher;
  1101. }
  1102. protected void engineInitVerify(PublicKey publicKey)
  1103. throws InvalidKeyException {
  1104. cipher.init(Cipher.DECRYPT_MODE, publicKey);
  1105. if (data == null) {
  1106. data = new ByteArrayOutputStream(128);
  1107. } else {
  1108. data.reset();
  1109. }
  1110. }
  1111. protected void engineInitSign(PrivateKey privateKey)
  1112. throws InvalidKeyException {
  1113. cipher.init(Cipher.ENCRYPT_MODE, privateKey);
  1114. data = null;
  1115. }
  1116. protected void engineInitSign(PrivateKey privateKey,
  1117. SecureRandom random) throws InvalidKeyException {
  1118. cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
  1119. data = null;
  1120. }
  1121. protected void engineUpdate(byte b) throws SignatureException {
  1122. engineUpdate(new byte[] {b}, 0, 1);
  1123. }
  1124. protected void engineUpdate(byte[] b, int off, int len)
  1125. throws SignatureException {
  1126. if (data != null) {
  1127. data.write(b, off, len);
  1128. return;
  1129. }
  1130. byte[] out = cipher.update(b, off, len);
  1131. if ((out != null) && (out.length != 0)) {
  1132. throw new SignatureException
  1133. ("Cipher unexpectedly returned data");
  1134. }
  1135. }
  1136. protected byte[] engineSign() throws SignatureException {
  1137. try {
  1138. return cipher.doFinal();
  1139. } catch (IllegalBlockSizeException e) {
  1140. throw new SignatureException("doFinal() failed", e);
  1141. } catch (BadPaddingException e) {
  1142. throw new SignatureException("doFinal() failed", e);
  1143. }
  1144. }
  1145. protected boolean engineVerify(byte[] sigBytes)
  1146. throws SignatureException {
  1147. try {
  1148. byte[] out = cipher.doFinal(sigBytes);
  1149. byte[] dataBytes = data.toByteArray();
  1150. data.reset();
  1151. return Arrays.equals(out, dataBytes);
  1152. } catch (BadPaddingException e) {
  1153. // e.g. wrong public key used
  1154. // return false rather than throwing exception
  1155. return false;
  1156. } catch (IllegalBlockSizeException e) {
  1157. throw new SignatureException("doFinal() failed", e);
  1158. }
  1159. }
  1160. protected void engineSetParameter(String param, Object value)
  1161. throws InvalidParameterException {
  1162. throw new InvalidParameterException("Parameters not supported");
  1163. }
  1164. protected Object engineGetParameter(String param)
  1165. throws InvalidParameterException {
  1166. throw new InvalidParameterException("Parameters not supported");
  1167. }
  1168. }
  1169. }