1. /*
  2. * @(#)KeyPairGenerator.java 1.42 01/11/29
  3. *
  4. * Copyright 2002 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. /**
  10. * The KeyPairGenerator class is used to generate pairs of
  11. * public and private keys. Key pair generators are constructed using the
  12. * <code>getInstance</code> factory methods (static methods that
  13. * return instances of a given class).
  14. *
  15. * <p>A Key pair generator for a particular algorithm creates a public/private
  16. * key pair that can be used with this algorithm. It also associates
  17. * algorithm-specific parameters with each of the generated keys.
  18. *
  19. * <p>There are two ways to generate a key pair: in an algorithm-independent
  20. * manner, and in an algorithm-specific manner.
  21. * The only difference between the two is the initialization of the object:
  22. *
  23. * <ul>
  24. * <li><b>Algorithm-Independent Initialization</b>
  25. * <p>All key pair generators share the concepts of a keysize and a
  26. * source of randomness. The keysize is interpreted differently for different
  27. * algorithms (e.g., in the case of the <i>DSA</i> algorithm, the keysize
  28. * corresponds to the length of the modulus).
  29. * There is an
  30. * <a href = "#initialize(int, java.security.SecureRandom)">initialize</a>
  31. * method in this KeyPairGenerator class that takes these two universally
  32. * shared types of arguments. There is also one that takes just a
  33. * <code>keysize</code> argument, and uses the <code>SecureRandom</code>
  34. * implementation of the highest-priority installed provider as the source
  35. * of randomness. (If none of the installed providers supply an implementation
  36. * of <code>SecureRandom</code>, a system-provided source of randomness is
  37. * used.)
  38. *
  39. * <p>Since no other parameters are specified when you call the above
  40. * algorithm-independent <code>initialize</code> methods, it is up to the
  41. * provider what to do about the algorithm-specific parameters (if any) to be
  42. * associated with each of the keys.
  43. *
  44. * <p>If the algorithm is the <i>DSA</i> algorithm, and the keysize (modulus
  45. * size) is 512, 768, or 1024, then the <i>Sun</i> provider uses a set of
  46. * precomputed values for the <code>p</code>, <code>q</code>, and
  47. * <code>g</code> parameters. If the modulus size is not one of the above
  48. * values, the <i>Sun</i> provider creates a new set of parameters. Other
  49. * providers might have precomputed parameter sets for more than just the
  50. * three modulus sizes mentioned above. Still others might not have a list of
  51. * precomputed parameters at all and instead always create new parameter sets.
  52. * <p>
  53. *
  54. * <li><b>Algorithm-Specific Initialization</b>
  55. * <p>For situations where a set of algorithm-specific parameters already
  56. * exists (e.g., so-called <i>community parameters</i> in DSA), there are two
  57. * <a href = "#initialize(java.security.spec.AlgorithmParameterSpec)">
  58. * initialize</a> methods that have an <code>AlgorithmParameterSpec</code>
  59. * argument. One also has a <code>SecureRandom</code> argument, while the
  60. * the other uses the <code>SecureRandom</code>
  61. * implementation of the highest-priority installed provider as the source
  62. * of randomness. (If none of the installed providers supply an implementation
  63. * of <code>SecureRandom</code>, a system-provided source of randomness is
  64. * used.)
  65. * </ul>
  66. *
  67. * <p>In case the client does not explicitly initialize the KeyPairGenerator
  68. * (via a call to an <code>initialize</code> method), each provider must
  69. * supply (and document) a default initialization.
  70. * For example, the <i>Sun</i> provider uses a default modulus size (keysize)
  71. * of 1024 bits.
  72. *
  73. * <p>Note that this class is abstract and extends from
  74. * <code>KeyPairGeneratorSpi</code> for historical reasons.
  75. * Application developers should only take notice of the methods defined in
  76. * this <code>KeyPairGenerator</code> class; all the methods in
  77. * the superclass are intended for cryptographic service providers who wish to
  78. * supply their own implementations of key pair generators.
  79. *
  80. * @author Benjamin Renaud
  81. *
  82. * @version 1.42, 01/11/29
  83. *
  84. * @see java.security.spec.AlgorithmParameterSpec
  85. */
  86. public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
  87. private String algorithm;
  88. // The provider
  89. private Provider provider;
  90. /**
  91. * Creates a KeyPairGenerator object for the specified algorithm.
  92. *
  93. * @param algorithm the standard string name of the algorithm.
  94. * See Appendix A in the <a href=
  95. * "../../../guide/security/CryptoSpec.html#AppA">
  96. * Java Cryptography Architecture API Specification & Reference </a>
  97. * for information about standard algorithm names.
  98. */
  99. protected KeyPairGenerator(String algorithm) {
  100. this.algorithm = algorithm;
  101. }
  102. /**
  103. * Returns the standard name of the algorithm for this key pair generator.
  104. * See Appendix A in the <a href=
  105. * "../../../guide/security/CryptoSpec.html#AppA">
  106. * Java Cryptography Architecture API Specification & Reference </a>
  107. * for information about standard algorithm names.
  108. *
  109. * @return the standard string name of the algorithm.
  110. */
  111. public String getAlgorithm() {
  112. return this.algorithm;
  113. }
  114. /**
  115. * Generates a KeyPairGenerator object that implements the specified digest
  116. * algorithm. If the default provider package
  117. * provides an implementation of the requested digest algorithm,
  118. * an instance of KeyPairGenerator containing that implementation is
  119. * returned.
  120. * If the algorithm is not available in the default
  121. * package, other packages are searched.
  122. *
  123. * @param algorithm the standard string name of the algorithm.
  124. * See Appendix A in the <a href=
  125. * "../../../guide/security/CryptoSpec.html#AppA">
  126. * Java Cryptography Architecture API Specification & Reference </a>
  127. * for information about standard algorithm names.
  128. *
  129. * @return the new KeyPairGenerator object.
  130. *
  131. * @exception NoSuchAlgorithmException if the algorithm is
  132. * not available in the environment.
  133. */
  134. public static KeyPairGenerator getInstance(String algorithm)
  135. throws NoSuchAlgorithmException {
  136. try {
  137. Object[] objs = Security.getImpl(algorithm, "KeyPairGenerator",
  138. null);
  139. if (objs[0] instanceof KeyPairGenerator) {
  140. KeyPairGenerator keyPairGen = (KeyPairGenerator)objs[0];
  141. keyPairGen.provider = (Provider)objs[1];
  142. return keyPairGen;
  143. } else {
  144. KeyPairGenerator delegate =
  145. new Delegate((KeyPairGeneratorSpi)objs[0], algorithm);
  146. delegate.provider = (Provider)objs[1];
  147. return delegate;
  148. }
  149. } catch(NoSuchProviderException e) {
  150. throw new NoSuchAlgorithmException(algorithm + " not found");
  151. }
  152. }
  153. /**
  154. * Generates a KeyPairGenerator object implementing the specified
  155. * algorithm, as supplied from the specified provider,
  156. * if such an algorithm is available from the provider.
  157. *
  158. * @param algorithm the standard string name of the algorithm.
  159. * See Appendix A in the <a href=
  160. * "../../../guide/security/CryptoSpec.html#AppA">
  161. * Java Cryptography Architecture API Specification & Reference </a>
  162. * for information about standard algorithm names.
  163. *
  164. * @param provider the string name of the provider.
  165. *
  166. * @return the new KeyPairGenerator object.
  167. *
  168. * @exception NoSuchAlgorithmException if the algorithm is
  169. * not available from the provider.
  170. *
  171. * @exception NoSuchProviderException if the provider is not
  172. * available in the environment.
  173. *
  174. * @see Provider
  175. */
  176. public static KeyPairGenerator getInstance(String algorithm,
  177. String provider)
  178. throws NoSuchAlgorithmException, NoSuchProviderException
  179. {
  180. if (provider == null || provider.length() == 0)
  181. throw new IllegalArgumentException("missing provider");
  182. Object[] objs = Security.getImpl(algorithm, "KeyPairGenerator",
  183. provider);
  184. if (objs[0] instanceof KeyPairGenerator) {
  185. KeyPairGenerator keyPairGen = (KeyPairGenerator)objs[0];
  186. keyPairGen.provider = (Provider)objs[1];
  187. return keyPairGen;
  188. } else {
  189. KeyPairGenerator delegate =
  190. new Delegate((KeyPairGeneratorSpi)objs[0], algorithm);
  191. delegate.provider = (Provider)objs[1];
  192. return delegate;
  193. }
  194. }
  195. /**
  196. * Returns the provider of this key pair generator object.
  197. *
  198. * @return the provider of this key pair generator object
  199. */
  200. public final Provider getProvider() {
  201. return this.provider;
  202. }
  203. /**
  204. * Initializes the key pair generator for a certain keysize using
  205. * a default parameter set and the <code>SecureRandom</code>
  206. * implementation of the highest-priority installed provider as the source
  207. * of randomness.
  208. * (If none of the installed providers supply an implementation of
  209. * <code>SecureRandom</code>, a system-provided source of randomness is
  210. * used.)
  211. *
  212. * @param keysize the keysize. This is an
  213. * algorithm-specific metric, such as modulus length, specified in
  214. * number of bits.
  215. */
  216. public void initialize(int keysize) {
  217. initialize(keysize, new SecureRandom());
  218. }
  219. /**
  220. * Initializes the key pair generator for a certain keysize with
  221. * the given source of randomness (and a default parameter set).
  222. *
  223. * @param keysize the keysize. This is an
  224. * algorithm-specific metric, such as modulus length, specified in
  225. * number of bits.
  226. * @param random the source of randomness.
  227. *
  228. * @since JDK1.2
  229. */
  230. public void initialize(int keysize, SecureRandom random) {
  231. // This does nothing, because either
  232. // 1. the implementation object returned by getInstance() is an
  233. // instance of KeyPairGenerator which has its own
  234. // initialize(keysize, random) method, so the application would
  235. // be calling that method directly, or
  236. // 2. the implementation returned by getInstance() is an instance
  237. // of Delegate, in which case initialize(keysize, random) is
  238. // overridden to call the corresponding SPI method.
  239. // (This is a special case, because the API and SPI method have the
  240. // same name.)
  241. }
  242. /**
  243. * Initializes the key pair generator using the specified parameter
  244. * set and the <code>SecureRandom</code>
  245. * implementation of the highest-priority installed provider as the source
  246. * of randomness.
  247. * (If none of the installed providers supply an implementation of
  248. * <code>SecureRandom</code>, a system-provided source of randomness is
  249. * used.).
  250. *
  251. * <p>This concrete method has been added to this previously-defined
  252. * abstract class.
  253. * This method calls the KeyPairGeneratorSpi <a href =
  254. * "KeyPairGeneratorSpi.html#
  255. * initialize(java.security.spec.AlgorithmParameterSpec,
  256. * java.security.SecureRandom)">initialize</a> method,
  257. * passing it <code>params</code> and a source of randomness (obtained
  258. * from the highest-priority installed provider or system-provided if none
  259. * of the installed providers supply one).
  260. * That <code>initialize</code> method always throws an
  261. * UnsupportedOperationException if it is not overridden by the provider.
  262. *
  263. * @param params the parameter set used to generate the keys.
  264. *
  265. * @exception InvalidAlgorithmParameterException if the given parameters
  266. * are inappropriate for this key pair generator.
  267. *
  268. * @since JDK1.2
  269. */
  270. public void initialize(AlgorithmParameterSpec params)
  271. throws InvalidAlgorithmParameterException {
  272. initialize(params, new SecureRandom());
  273. }
  274. /**
  275. * Initializes the key pair generator with the given parameter
  276. * set and source of randomness.
  277. *
  278. * <p>This concrete method has been added to this previously-defined
  279. * abstract class.
  280. * This method calls the KeyPairGeneratorSpi <a href =
  281. * "KeyPairGeneratorSpi.html#
  282. * initialize(java.security.spec.AlgorithmParameterSpec,
  283. * java.security.SecureRandom)">initialize</a> method,
  284. * passing it <code>params</code> and <code>random</code>.
  285. * That <code>initialize</code>
  286. * method always throws an
  287. * UnsupportedOperationException if it is not overridden by the provider.
  288. *
  289. * @param params the parameter set used to generate the keys.
  290. * @param random the source of randomness.
  291. *
  292. * @exception InvalidAlgorithmParameterException if the given parameters
  293. * are inappropriate for this key pair generator.
  294. *
  295. * @since JDK1.2
  296. */
  297. public void initialize(AlgorithmParameterSpec params,
  298. SecureRandom random)
  299. throws InvalidAlgorithmParameterException
  300. {
  301. // This does nothing, because either
  302. // 1. the implementation object returned by getInstance() is an
  303. // instance of KeyPairGenerator which has its own
  304. // initialize(params, random) method, so the application would
  305. // be calling that method directly, or
  306. // 2. the implementation returned by getInstance() is an instance
  307. // of Delegate, in which case initialize(params, random) is
  308. // overridden to call the corresponding SPI method.
  309. // (This is a special case, because the API and SPI method have the
  310. // same name.)
  311. }
  312. /**
  313. * Generates a key pair. Unless an initialization method is called
  314. * using a KeyPairGenerator interface, algorithm-specific defaults
  315. * will be used. This will generate a new key pair every time it
  316. * is called.
  317. *
  318. * @return the generated key pair
  319. *
  320. * @since JDK1.2
  321. */
  322. public final KeyPair genKeyPair() {
  323. return generateKeyPair();
  324. }
  325. /*
  326. * The following class allows providers to extend from KeyPairGeneratorSpi
  327. * rather than from KeyPairGenerator. It represents a KeyPairGenerator
  328. * with an encapsulated, provider-supplied SPI object (of type
  329. * KeyPairGeneratorSpi).
  330. * If the provider implementation is an instance of KeyPairGeneratorSpi,
  331. * the getInstance() methods above return an instance of this class, with
  332. * the SPI object encapsulated.
  333. *
  334. * Note: All SPI methods from the original KeyPairGenerator class have been
  335. * moved up the hierarchy into a new class (KeyPairGeneratorSpi), which has
  336. * been interposed in the hierarchy between the API (KeyPairGenerator)
  337. * and its original parent (Object).
  338. */
  339. static class Delegate extends KeyPairGenerator {
  340. // The provider implementation (delegate)
  341. private KeyPairGeneratorSpi kpairGenSpi;
  342. // constructor
  343. public Delegate(KeyPairGeneratorSpi kpairGenSpi, String algorithm) {
  344. super(algorithm);
  345. this.kpairGenSpi = kpairGenSpi;
  346. }
  347. // engine method
  348. public void initialize(int keysize, SecureRandom random) {
  349. kpairGenSpi.initialize(keysize, random);
  350. }
  351. // engine method
  352. public void initialize(AlgorithmParameterSpec params,
  353. SecureRandom random)
  354. throws InvalidAlgorithmParameterException {
  355. kpairGenSpi.initialize(params, random);;
  356. }
  357. // engine method
  358. public KeyPair generateKeyPair() {
  359. return kpairGenSpi.generateKeyPair();
  360. }
  361. }
  362. }