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