1. /*
  2. * @(#)Signature.java 1.85 00/02/02
  3. *
  4. * Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.security;
  11. import java.security.spec.AlgorithmParameterSpec;
  12. import java.util.*;
  13. import java.io.*;
  14. import java.security.cert.Certificate;
  15. import java.security.cert.X509Certificate;
  16. /**
  17. * This Signature class is used to provide applications the functionality
  18. * of a digital signature algorithm. Digital signatures are used for
  19. * authentication and integrity assurance of digital data.
  20. *
  21. * <p> The signature algorithm can be, among others, the NIST standard
  22. * DSA, using DSA and SHA-1. The DSA algorithm using the
  23. * SHA-1 message digest algorithm can be specified as <tt>SHA1withDSA</tt>.
  24. * In the case of RSA, there are multiple choices for the message digest
  25. * algorithm, so the signing algorithm could be specified as, for example,
  26. * <tt>MD2withRSA</tt>, <tt>MD5withRSA</tt>, or <tt>SHA1withRSA</tt>.
  27. * The algorithm name must be specified, as there is no default.
  28. *
  29. * <p>Like other algorithm-based classes in Java Security, Signature
  30. * provides implementation-independent algorithms, whereby a caller
  31. * (application code) requests a particular signature algorithm
  32. * and is handed back a properly initialized Signature object. It is
  33. * also possible, if desired, to request a particular algorithm from a
  34. * particular provider. See the <code>getInstance </code> methods.
  35. *
  36. * <p>Thus, there are two ways to request a Signature algorithm object: by
  37. * specifying either just an algorithm name, or both an algorithm name
  38. * and a package provider. <ul>
  39. *
  40. * <li>If just an algorithm name is specified, the system will
  41. * determine if there is an implementation of the algorithm requested
  42. * available in the environment, and if there is more than one, if
  43. * there is a preferred one.<p>
  44. *
  45. * <li>If both an algorithm name and a package provider are specified,
  46. * the system will determine if there is an implementation of the
  47. * algorithm in the package requested, and throw an exception if there
  48. * is not.
  49. *
  50. * </ul>
  51. *
  52. * <p>A Signature object can be used to generate and verify digital
  53. * signatures.
  54. *
  55. * <p>There are three phases to the use of a Signature object for
  56. * either signing data or verifying a signature:<ol>
  57. *
  58. * <li>Initialization, with either
  59. *
  60. * <ul>
  61. *
  62. * <li>a public key, which initializes the signature for
  63. * verification (see {@link #initVerify(PublicKey) initVerify}), or
  64. *
  65. * <li>a private key (and optionally a Secure Random Number Generator),
  66. * which initializes the signature for signing
  67. * (see {@link #initSign(PrivateKey)}
  68. * and {@link #initSign(PrivateKey, SecureRandom)}).
  69. *
  70. * </ul><p>
  71. *
  72. * <li>Updating<p>
  73. *
  74. * <p>Depending on the type of initialization, this will update the
  75. * bytes to be signed or verified. See the
  76. * {@link #update(byte) update} methods.<p>
  77. *
  78. * <li>Signing or Verifying a signature on all updated bytes. See the
  79. * {@link #sign() sign} methods and the {@link #verify(byte[]) verify}
  80. * method.
  81. *
  82. * </ol>
  83. *
  84. * <p>Note that this class is abstract and extends from
  85. * <code>SignatureSpi</code> for historical reasons.
  86. * Application developers should only take notice of the methods defined in
  87. * this <code>Signature</code> class; all the methods in
  88. * the superclass are intended for cryptographic service providers who wish to
  89. * supply their own implementations of digital signature algorithms.
  90. *
  91. * @author Benjamin Renaud
  92. *
  93. * @version 1.85, 02/02/00
  94. */
  95. public abstract class Signature extends SignatureSpi {
  96. /* Are we in debugging mode? */
  97. private static final boolean debug = false;
  98. /*
  99. * The algorithm for this signature object.
  100. * This value is used to map an OID to the particular algorithm.
  101. * The mapping is done in AlgorithmObject.algOID(String algorithm)
  102. */
  103. private String algorithm;
  104. // The provider
  105. private Provider provider;
  106. /**
  107. * Possible {@link #state} value, signifying that
  108. * this signature object has not yet been initialized.
  109. */
  110. protected final static int UNINITIALIZED = 0;
  111. /**
  112. * Possible {@link #state} value, signifying that
  113. * this signature object has been initialized for signing.
  114. */
  115. protected final static int SIGN = 2;
  116. /**
  117. * Possible {@link #state} value, signifying that
  118. * this signature object has been initialized for verification.
  119. */
  120. protected final static int VERIFY = 3;
  121. /**
  122. * Current state of this signature object.
  123. */
  124. protected int state = UNINITIALIZED;
  125. /**
  126. * Creates a Signature object for the specified algorithm.
  127. *
  128. * @param algorithm the standard string name of the algorithm.
  129. * See Appendix A in the <a href=
  130. * "../../../guide/security/CryptoSpec.html#AppA">
  131. * Java Cryptography Architecture API Specification & Reference </a>
  132. * for information about standard algorithm names.
  133. */
  134. protected Signature(String algorithm) {
  135. this.algorithm = algorithm;
  136. }
  137. /**
  138. * Generates a Signature object that implements the specified digest
  139. * algorithm. If the default provider package
  140. * provides an implementation of the requested digest algorithm,
  141. * an instance of Signature containing that implementation is returned.
  142. * If the algorithm is not available in the default
  143. * package, other packages are searched.
  144. *
  145. * @param algorithm the standard name of the algorithm requested.
  146. * See Appendix A in the <a href=
  147. * "../../../guide/security/CryptoSpec.html#AppA">
  148. * Java Cryptography Architecture API Specification & Reference </a>
  149. * for information about standard algorithm names.
  150. *
  151. * @return the new Signature object.
  152. *
  153. * @exception NoSuchAlgorithmException if the algorithm is
  154. * not available in the environment.
  155. */
  156. public static Signature getInstance(String algorithm)
  157. throws NoSuchAlgorithmException {
  158. try {
  159. Object[] objs = Security.getImpl(algorithm, "Signature", null);
  160. if (objs[0] instanceof Signature) {
  161. Signature sig = (Signature)objs[0];
  162. sig.provider = (Provider)objs[1];
  163. return sig;
  164. } else {
  165. Signature delegate =
  166. new Delegate((SignatureSpi)objs[0], algorithm);
  167. delegate.provider = (Provider)objs[1];
  168. return delegate;
  169. }
  170. } catch(NoSuchProviderException e) {
  171. throw new NoSuchAlgorithmException(algorithm + " not found");
  172. }
  173. }
  174. /**
  175. * Generates a Signature object implementing the specified
  176. * algorithm, as supplied from the specified provider, if such an
  177. * algorithm is available from the provider.
  178. *
  179. * @param algorithm the name of the algorithm requested.
  180. * See Appendix A in the <a href=
  181. * "../../../guide/security/CryptoSpec.html#AppA">
  182. * Java Cryptography Architecture API Specification & Reference </a>
  183. * for information about standard algorithm names.
  184. *
  185. * @param provider the name of the provider.
  186. *
  187. * @return the new Signature object.
  188. *
  189. * @exception NoSuchAlgorithmException if the algorithm is
  190. * not available in the package supplied by the requested
  191. * provider.
  192. *
  193. * @exception NoSuchProviderException if the provider is not
  194. * available in the environment.
  195. *
  196. * @see Provider
  197. */
  198. public static Signature getInstance(String algorithm, String provider)
  199. throws NoSuchAlgorithmException, NoSuchProviderException
  200. {
  201. if (provider == null || provider.length() == 0)
  202. throw new IllegalArgumentException("missing provider");
  203. Object[] objs = Security.getImpl(algorithm, "Signature", provider);
  204. if (objs[0] instanceof Signature) {
  205. Signature sig = (Signature)objs[0];
  206. sig.provider = (Provider)objs[1];
  207. return sig;
  208. } else {
  209. Signature delegate =
  210. new Delegate((SignatureSpi)objs[0], algorithm);
  211. delegate.provider = (Provider)objs[1];
  212. return delegate;
  213. }
  214. }
  215. /**
  216. * Returns the provider of this signature object.
  217. *
  218. * @return the provider of this signature object
  219. */
  220. public final Provider getProvider() {
  221. return this.provider;
  222. }
  223. /**
  224. * Initializes this object for verification. If this method is called
  225. * again with a different argument, it negates the effect
  226. * of this call.
  227. *
  228. * @param publicKey the public key of the identity whose signature is
  229. * going to be verified.
  230. *
  231. * @exception InvalidKeyException if the key is invalid.
  232. */
  233. public final void initVerify(PublicKey publicKey)
  234. throws InvalidKeyException {
  235. engineInitVerify(publicKey);
  236. state = VERIFY;
  237. }
  238. /**
  239. * Initializes this object for verification, using the public key from
  240. * the given certificate.
  241. * <p>If the certificate is of type X.509 and has a <i>key usage</i>
  242. * extension field marked as critical, and the value of the <i>key usage</i>
  243. * extension field implies that the public key in
  244. * the certificate and its corresponding private key are not
  245. * supposed to be used for digital signatures, an <code>InvalidKeyException</code>
  246. * is thrown.
  247. *
  248. * @param certificate the certificate of the identity whose signature is
  249. * going to be verified.
  250. *
  251. * @exception InvalidKeyException if the public key in the certificate
  252. * is not encoded properly or does not include required parameter
  253. * information or cannot be used for digital signature purposes.
  254. */
  255. public final void initVerify(Certificate certificate)
  256. throws InvalidKeyException {
  257. // If the certificate is of type X509Certificate,
  258. // we should check whether it has a Key Usage
  259. // extension marked as critical.
  260. if (certificate instanceof java.security.cert.X509Certificate) {
  261. // Check whether the cert has a key usage extension
  262. // marked as a critical extension.
  263. // The OID for KeyUsage extension is 2.5.29.15.
  264. X509Certificate cert = (X509Certificate)certificate;
  265. Set critSet = cert.getCriticalExtensionOIDs();
  266. if (critSet != null && !critSet.isEmpty()
  267. && critSet.contains(new String("2.5.29.15"))) {
  268. boolean[] keyUsageInfo = cert.getKeyUsage();
  269. // keyUsageInfo[0] is for digitalSignature.
  270. if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
  271. throw new InvalidKeyException("Wrong key usage");
  272. }
  273. }
  274. PublicKey publicKey = certificate.getPublicKey();
  275. engineInitVerify(publicKey);
  276. state = VERIFY;
  277. }
  278. /**
  279. * Initialize this object for signing. If this method is called
  280. * again with a different argument, it negates the effect
  281. * of this call.
  282. *
  283. * @param privateKey the private key of the identity whose signature
  284. * is going to be generated.
  285. *
  286. * @exception InvalidKeyException if the key is invalid.
  287. */
  288. public final void initSign(PrivateKey privateKey)
  289. throws InvalidKeyException {
  290. engineInitSign(privateKey);
  291. state = SIGN;
  292. }
  293. /**
  294. * Initialize this object for signing. If this method is called
  295. * again with a different argument, it negates the effect
  296. * of this call.
  297. *
  298. * @param privateKey the private key of the identity whose signature
  299. * is going to be generated.
  300. *
  301. * @param random the source of randomness for this signature.
  302. *
  303. * @exception InvalidKeyException if the key is invalid.
  304. */
  305. public final void initSign(PrivateKey privateKey, SecureRandom random)
  306. throws InvalidKeyException {
  307. engineInitSign(privateKey, random);
  308. state = SIGN;
  309. }
  310. /**
  311. * Returns the signature bytes of all the data updated.
  312. * The format of the signature depends on the underlying
  313. * signature scheme.
  314. *
  315. * <p>A call to this method resets this signature object to the state
  316. * it was in when previously initialized for signing via a
  317. * call to <code>initSign(PrivateKey)</code>. That is, the object is
  318. * reset and available to generate another signature from the same
  319. * signer, if desired, via new calls to <code>update</code> and
  320. * <code>sign</code>.
  321. *
  322. * @return the signature bytes of the signing operation's result.
  323. *
  324. * @exception SignatureException if this signature object is not
  325. * initialized properly.
  326. */
  327. public final byte[] sign() throws SignatureException {
  328. if (state == SIGN) {
  329. return engineSign();
  330. }
  331. throw new SignatureException("object not initialized for " +
  332. "signing");
  333. }
  334. /**
  335. * Finishes the signature operation and stores the resulting signature
  336. * bytes in the provided buffer <code>outbuf</code>, starting at
  337. * <code>offset</code>.
  338. * The format of the signature depends on the underlying
  339. * signature scheme.
  340. *
  341. * <p>This signature object is reset to its initial state (the state it
  342. * was in after a call to one of the <code>initSign</code> methods) and
  343. * can be reused to generate further signatures with the same private key.
  344. *
  345. * @param outbuf buffer for the signature result.
  346. *
  347. * @param offset offset into <code>outbuf</code> where the signature is
  348. * stored.
  349. *
  350. * @param len number of bytes within <code>outbuf</code> allotted for the
  351. * signature.
  352. *
  353. * @return the number of bytes placed into <code>outbuf</code>.
  354. *
  355. * @exception SignatureException if an error occurs or <code>len</code>
  356. * is less than the actual signature length.
  357. *
  358. * @since 1.2
  359. */
  360. public final int sign(byte[] outbuf, int offset, int len)
  361. throws SignatureException {
  362. if (outbuf == null) {
  363. throw new IllegalArgumentException("No output buffer given");
  364. }
  365. if (outbuf.length - offset < len) {
  366. throw new IllegalArgumentException
  367. ("Output buffer too small for specified offset and length");
  368. }
  369. if (state != SIGN) {
  370. throw new SignatureException("object not initialized for " +
  371. "signing");
  372. }
  373. return engineSign(outbuf, offset, len);
  374. }
  375. /**
  376. * Verifies the passed-in signature.
  377. *
  378. * <p>A call to this method resets this signature object to the state
  379. * it was in when previously initialized for verification via a
  380. * call to <code>initVerify(PublicKey)</code>. That is, the object is
  381. * reset and available to verify another signature from the identity
  382. * whose public key was specified in the call to <code>initVerify</code>.
  383. *
  384. * @param signature the signature bytes to be verified.
  385. *
  386. * @return true if the signature was verified, false if not.
  387. *
  388. * @exception SignatureException if this signature object is not
  389. * initialized properly, or the passed-in signature is improperly
  390. * encoded or of the wrong type, etc.
  391. */
  392. public final boolean verify(byte[] signature) throws SignatureException {
  393. if (state == VERIFY) {
  394. return engineVerify(signature);
  395. }
  396. throw new SignatureException("object not initialized for " +
  397. "verification");
  398. }
  399. /**
  400. * Updates the data to be signed or verified by a byte.
  401. *
  402. * @param b the byte to use for the update.
  403. *
  404. * @exception SignatureException if this signature object is not
  405. * initialized properly.
  406. */
  407. public final void update(byte b) throws SignatureException {
  408. if (state == VERIFY || state == SIGN) {
  409. engineUpdate(b);
  410. } else {
  411. throw new SignatureException("object not initialized for "
  412. + "signature or verification");
  413. }
  414. }
  415. /**
  416. * Updates the data to be signed or verified, using the specified
  417. * array of bytes.
  418. *
  419. * @param data the byte array to use for the update.
  420. *
  421. * @exception SignatureException if this signature object is not
  422. * initialized properly.
  423. */
  424. public final void update(byte[] data) throws SignatureException {
  425. update(data, 0, data.length);
  426. }
  427. /**
  428. * Updates the data to be signed or verified, using the specified
  429. * array of bytes, starting at the specified offset.
  430. *
  431. * @param data the array of bytes.
  432. * @param off the offset to start from in the array of bytes.
  433. * @param len the number of bytes to use, starting at offset.
  434. *
  435. * @exception SignatureException if this signature object is not
  436. * initialized properly.
  437. */
  438. public final void update(byte[] data, int off, int len)
  439. throws SignatureException {
  440. if (state == SIGN || state == VERIFY) {
  441. engineUpdate(data, off, len);
  442. } else {
  443. throw new SignatureException("object not initialized for "
  444. + "signature or verification");
  445. }
  446. }
  447. /**
  448. * Returns the name of the algorithm for this signature object.
  449. *
  450. * @return the name of the algorithm for this signature object.
  451. */
  452. public final String getAlgorithm() {
  453. return this.algorithm;
  454. }
  455. /**
  456. * Returns a string representation of this signature object,
  457. * providing information that includes the state of the object
  458. * and the name of the algorithm used.
  459. *
  460. * @return a string representation of this signature object.
  461. */
  462. public String toString() {
  463. String initState = "";
  464. switch (state) {
  465. case UNINITIALIZED:
  466. initState = "<not initialized>";
  467. break;
  468. case VERIFY:
  469. initState = "<initialized for verifying>";
  470. break;
  471. case SIGN:
  472. initState = "<initialized for signing>";
  473. break;
  474. }
  475. return "Signature object: " + getAlgorithm() + initState;
  476. }
  477. /**
  478. * Sets the specified algorithm parameter to the specified value.
  479. * This method supplies a general-purpose mechanism through
  480. * which it is possible to set the various parameters of this object.
  481. * A parameter may be any settable parameter for the algorithm, such as
  482. * a parameter size, or a source of random bits for signature generation
  483. * (if appropriate), or an indication of whether or not to perform
  484. * a specific but optional computation. A uniform algorithm-specific
  485. * naming scheme for each parameter is desirable but left unspecified
  486. * at this time.
  487. *
  488. * @param param the string identifier of the parameter.
  489. * @param value the parameter value.
  490. *
  491. * @exception InvalidParameterException if <code>param</code> is an
  492. * invalid parameter for this signature algorithm engine,
  493. * the parameter is already set
  494. * and cannot be set again, a security exception occurs, and so on.
  495. *
  496. * @deprecated Use
  497. * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
  498. * setParameter}.
  499. */
  500. public final void setParameter(String param, Object value)
  501. throws InvalidParameterException {
  502. engineSetParameter(param, value);
  503. }
  504. /**
  505. * Initializes this signature engine with the specified parameter set.
  506. *
  507. * @param params the parameters
  508. *
  509. * @exception InvalidAlgorithmParameterException if the given parameters
  510. * are inappropriate for this signature engine
  511. */
  512. public final void setParameter(AlgorithmParameterSpec params)
  513. throws InvalidAlgorithmParameterException {
  514. engineSetParameter(params);
  515. }
  516. /**
  517. * Gets the value of the specified algorithm parameter. This method
  518. * supplies a general-purpose mechanism through which it is possible to
  519. * get the various parameters of this object. A parameter may be any
  520. * settable parameter for the algorithm, such as a parameter size, or
  521. * a source of random bits for signature generation (if appropriate),
  522. * or an indication of whether or not to perform a specific but optional
  523. * computation. A uniform algorithm-specific naming scheme for each
  524. * parameter is desirable but left unspecified at this time.
  525. *
  526. * @param param the string name of the parameter.
  527. *
  528. * @return the object that represents the parameter value, or null if
  529. * there is none.
  530. *
  531. * @exception InvalidParameterException if <code>param</code> is an invalid
  532. * parameter for this engine, or another exception occurs while
  533. * trying to get this parameter.
  534. *
  535. * @deprecated
  536. */
  537. public final Object getParameter(String param)
  538. throws InvalidParameterException {
  539. return engineGetParameter(param);
  540. }
  541. /**
  542. * Returns a clone if the implementation is cloneable.
  543. *
  544. * @return a clone if the implementation is cloneable.
  545. *
  546. * @exception CloneNotSupportedException if this is called
  547. * on an implementation that does not support <code>Cloneable</code>.
  548. */
  549. public Object clone() throws CloneNotSupportedException {
  550. if (this instanceof Cloneable) {
  551. return super.clone();
  552. } else {
  553. throw new CloneNotSupportedException();
  554. }
  555. }
  556. // private debugging method.
  557. private static void debug(String statement) {
  558. if (debug) {
  559. System.err.println(statement);
  560. }
  561. }
  562. // private debugging method.
  563. private static void debug(Exception e) {
  564. if (debug) {
  565. e.printStackTrace();
  566. }
  567. }
  568. /*
  569. * The following class allows providers to extend from SignatureSpi
  570. * rather than from Signature. It represents a Signature with an
  571. * encapsulated, provider-supplied SPI object (of type SignatureSpi).
  572. * If the provider implementation is an instance of SignatureSpi, the
  573. * getInstance() methods above return an instance of this class, with
  574. * the SPI object encapsulated.
  575. *
  576. * Note: All SPI methods from the original Signature class have been
  577. * moved up the hierarchy into a new class (SignatureSpi), which has
  578. * been interposed in the hierarchy between the API (Signature)
  579. * and its original parent (Object).
  580. */
  581. static class Delegate extends Signature {
  582. // The provider implementation (delegate)
  583. private SignatureSpi sigSpi;
  584. // constructor
  585. public Delegate(SignatureSpi sigSpi, String algorithm) {
  586. super(algorithm);
  587. this.sigSpi = sigSpi;
  588. }
  589. /*
  590. * Returns a clone if the delegate is cloneable.
  591. *
  592. * @return a clone if the delegate is cloneable.
  593. *
  594. * @exception CloneNotSupportedException if this is called on a
  595. * delegate that does not support <code>Cloneable</code>.
  596. */
  597. public Object clone() throws CloneNotSupportedException {
  598. if (sigSpi instanceof Cloneable) {
  599. SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone();
  600. // Because 'algorithm' and 'provider' are private
  601. // members of our supertype, we must perform a cast to
  602. // access them.
  603. Signature that =
  604. new Delegate(sigSpiClone, ((Signature)this).algorithm);
  605. that.provider = ((Signature)this).provider;
  606. return that;
  607. } else {
  608. throw new CloneNotSupportedException();
  609. }
  610. }
  611. protected void engineInitVerify(PublicKey publicKey)
  612. throws InvalidKeyException {
  613. sigSpi.engineInitVerify(publicKey);
  614. }
  615. protected void engineInitSign(PrivateKey privateKey)
  616. throws InvalidKeyException {
  617. sigSpi.engineInitSign(privateKey);
  618. }
  619. protected void engineUpdate(byte b) throws SignatureException {
  620. sigSpi.engineUpdate(b);
  621. }
  622. protected void engineUpdate(byte[] b, int off, int len)
  623. throws SignatureException {
  624. sigSpi.engineUpdate(b, off, len);
  625. }
  626. protected byte[] engineSign() throws SignatureException {
  627. return sigSpi.engineSign();
  628. }
  629. protected int engineSign(byte[] outbuf, int offset, int len)
  630. throws SignatureException {
  631. return sigSpi.engineSign(outbuf, offset, len);
  632. }
  633. protected boolean engineVerify(byte[] sigBytes)
  634. throws SignatureException {
  635. return sigSpi.engineVerify(sigBytes);
  636. }
  637. protected void engineSetParameter(String param, Object value)
  638. throws InvalidParameterException {
  639. sigSpi.engineSetParameter(param, value);
  640. }
  641. protected void engineSetParameter(AlgorithmParameterSpec params)
  642. throws InvalidAlgorithmParameterException {
  643. sigSpi.engineSetParameter(params);
  644. }
  645. protected Object engineGetParameter(String param)
  646. throws InvalidParameterException {
  647. return sigSpi.engineGetParameter(param);
  648. }
  649. }
  650. }