1. /*
  2. * @(#)KeyPairGenerator.java 1.52 03/01/23
  3. *
  4. * Copyright 2003 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. * {@link #initialize(int, java.security.SecureRandom) initialize}
  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. * {@link #initialize(java.security.spec.AlgorithmParameterSpec)
  58. * initialize} 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.52, 01/23/03
  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. (String)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. * @exception IllegalArgumentException if the provider name is null
  175. * or empty.
  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. * Generates a KeyPairGenerator object implementing the specified
  200. * algorithm, as supplied from the specified provider,
  201. * if such an algorithm is available from the provider.
  202. * Note: the <code>provider</code> doesn't have to be registered.
  203. *
  204. * @param algorithm the standard string name of the algorithm.
  205. * See Appendix A in the <a href=
  206. * "../../../guide/security/CryptoSpec.html#AppA">
  207. * Java Cryptography Architecture API Specification & Reference </a>
  208. * for information about standard algorithm names.
  209. *
  210. * @param provider the provider.
  211. *
  212. * @return the new KeyPairGenerator object.
  213. *
  214. * @exception NoSuchAlgorithmException if the algorithm is
  215. * not available from the provider.
  216. *
  217. * @exception IllegalArgumentException if the <code>provider</code> is
  218. * null.
  219. *
  220. * @see Provider
  221. *
  222. * @since 1.4
  223. */
  224. public static KeyPairGenerator getInstance(String algorithm,
  225. Provider provider)
  226. throws NoSuchAlgorithmException
  227. {
  228. if (provider == null)
  229. throw new IllegalArgumentException("missing provider");
  230. Object[] objs = Security.getImpl(algorithm, "KeyPairGenerator",
  231. provider);
  232. if (objs[0] instanceof KeyPairGenerator) {
  233. KeyPairGenerator keyPairGen = (KeyPairGenerator)objs[0];
  234. keyPairGen.provider = (Provider)objs[1];
  235. return keyPairGen;
  236. } else {
  237. KeyPairGenerator delegate =
  238. new Delegate((KeyPairGeneratorSpi)objs[0], algorithm);
  239. delegate.provider = (Provider)objs[1];
  240. return delegate;
  241. }
  242. }
  243. /**
  244. * Returns the provider of this key pair generator object.
  245. *
  246. * @return the provider of this key pair generator object
  247. */
  248. public final Provider getProvider() {
  249. return this.provider;
  250. }
  251. /**
  252. * Initializes the key pair generator for a certain keysize using
  253. * a default parameter 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. * @param keysize the keysize. This is an
  261. * algorithm-specific metric, such as modulus length, specified in
  262. * number of bits.
  263. *
  264. * @exception InvalidParameterException if the <code>keysize</code> is not
  265. * supported by this KeyPairGenerator object.
  266. */
  267. public void initialize(int keysize) {
  268. initialize(keysize, new SecureRandom());
  269. }
  270. /**
  271. * Initializes the key pair generator for a certain keysize with
  272. * the given source of randomness (and a default parameter set).
  273. *
  274. * @param keysize the keysize. This is an
  275. * algorithm-specific metric, such as modulus length, specified in
  276. * number of bits.
  277. * @param random the source of randomness.
  278. *
  279. * @exception InvalidParameterException if the <code>keysize</code> is not
  280. * supported by this KeyPairGenerator object.
  281. *
  282. * @since 1.2
  283. */
  284. public void initialize(int keysize, SecureRandom random) {
  285. // This does nothing, because either
  286. // 1. the implementation object returned by getInstance() is an
  287. // instance of KeyPairGenerator which has its own
  288. // initialize(keysize, random) method, so the application would
  289. // be calling that method directly, or
  290. // 2. the implementation returned by getInstance() is an instance
  291. // of Delegate, in which case initialize(keysize, random) is
  292. // overridden to call the corresponding SPI method.
  293. // (This is a special case, because the API and SPI method have the
  294. // same name.)
  295. }
  296. /**
  297. * Initializes the key pair generator using the specified parameter
  298. * set and the <code>SecureRandom</code>
  299. * implementation of the highest-priority installed provider as the source
  300. * of randomness.
  301. * (If none of the installed providers supply an implementation of
  302. * <code>SecureRandom</code>, a system-provided source of randomness is
  303. * used.).
  304. *
  305. * <p>This concrete method has been added to this previously-defined
  306. * abstract class.
  307. * This method calls the KeyPairGeneratorSpi
  308. * {@link KeyPairGeneratorSpi.html#
  309. * initialize(java.security.spec.AlgorithmParameterSpec,
  310. * java.security.SecureRandom) initialize} method,
  311. * passing it <code>params</code> and a source of randomness (obtained
  312. * from the highest-priority installed provider or system-provided if none
  313. * of the installed providers supply one).
  314. * That <code>initialize</code> method always throws an
  315. * UnsupportedOperationException if it is not overridden by the provider.
  316. *
  317. * @param params the parameter set used to generate the keys.
  318. *
  319. * @exception InvalidAlgorithmParameterException if the given parameters
  320. * are inappropriate for this key pair generator.
  321. *
  322. * @since 1.2
  323. */
  324. public void initialize(AlgorithmParameterSpec params)
  325. throws InvalidAlgorithmParameterException {
  326. initialize(params, new SecureRandom());
  327. }
  328. /**
  329. * Initializes the key pair generator with the given parameter
  330. * set and source of randomness.
  331. *
  332. * <p>This concrete method has been added to this previously-defined
  333. * abstract class.
  334. * This method calls the KeyPairGeneratorSpi {@link
  335. * KeyPairGeneratorSpi.html#
  336. * initialize(java.security.spec.AlgorithmParameterSpec,
  337. * java.security.SecureRandom) initialize} method,
  338. * passing it <code>params</code> and <code>random</code>.
  339. * That <code>initialize</code>
  340. * method always throws an
  341. * UnsupportedOperationException if it is not overridden by the provider.
  342. *
  343. * @param params the parameter set used to generate the keys.
  344. * @param random the source of randomness.
  345. *
  346. * @exception InvalidAlgorithmParameterException if the given parameters
  347. * are inappropriate for this key pair generator.
  348. *
  349. * @since 1.2
  350. */
  351. public void initialize(AlgorithmParameterSpec params,
  352. SecureRandom random)
  353. throws InvalidAlgorithmParameterException
  354. {
  355. // This does nothing, because either
  356. // 1. the implementation object returned by getInstance() is an
  357. // instance of KeyPairGenerator which has its own
  358. // initialize(params, random) method, so the application would
  359. // be calling that method directly, or
  360. // 2. the implementation returned by getInstance() is an instance
  361. // of Delegate, in which case initialize(params, random) is
  362. // overridden to call the corresponding SPI method.
  363. // (This is a special case, because the API and SPI method have the
  364. // same name.)
  365. }
  366. /**
  367. * Generates a key pair.
  368. *
  369. * <p>If this KeyPairGenerator has not been initialized explicitly,
  370. * provider-specific defaults will be used for the size and other
  371. * (algorithm-specific) values of the generated keys.
  372. *
  373. * <p>This will generate a new key pair every time it is called.
  374. *
  375. * <p>This method is functionally equivalent to
  376. * {@link #generateKeyPair() generateKeyPair}.
  377. *
  378. * @return the generated key pair
  379. *
  380. * @since 1.2
  381. */
  382. public final KeyPair genKeyPair() {
  383. return generateKeyPair();
  384. }
  385. /**
  386. * Generates a key pair.
  387. *
  388. * <p>If this KeyPairGenerator has not been initialized explicitly,
  389. * provider-specific defaults will be used for the size and other
  390. * (algorithm-specific) values of the generated keys.
  391. *
  392. * <p>This will generate a new key pair every time it is called.
  393. *
  394. * <p>This method is functionally equivalent to
  395. * {@link #genKeyPair() genKeyPair}.
  396. *
  397. * @return the generated key pair
  398. */
  399. public KeyPair generateKeyPair() {
  400. // This does nothing (except returning null), because either:
  401. //
  402. // 1. the implementation object returned by getInstance() is an
  403. // instance of KeyPairGenerator which has its own implementation
  404. // of generateKeyPair (overriding this one), so the application
  405. // would be calling that method directly, or
  406. //
  407. // 2. the implementation returned by getInstance() is an instance
  408. // of Delegate, in which case generateKeyPair is
  409. // overridden to invoke the corresponding SPI method.
  410. //
  411. // (This is a special case, because in JDK 1.1.x the generateKeyPair
  412. // method was used both as an API and a SPI method.)
  413. return null;
  414. }
  415. /*
  416. * The following class allows providers to extend from KeyPairGeneratorSpi
  417. * rather than from KeyPairGenerator. It represents a KeyPairGenerator
  418. * with an encapsulated, provider-supplied SPI object (of type
  419. * KeyPairGeneratorSpi).
  420. * If the provider implementation is an instance of KeyPairGeneratorSpi,
  421. * the getInstance() methods above return an instance of this class, with
  422. * the SPI object encapsulated.
  423. *
  424. * Note: All SPI methods from the original KeyPairGenerator class have been
  425. * moved up the hierarchy into a new class (KeyPairGeneratorSpi), which has
  426. * been interposed in the hierarchy between the API (KeyPairGenerator)
  427. * and its original parent (Object).
  428. */
  429. static class Delegate extends KeyPairGenerator {
  430. // The provider implementation (delegate)
  431. private KeyPairGeneratorSpi kpairGenSpi;
  432. // constructor
  433. public Delegate(KeyPairGeneratorSpi kpairGenSpi, String algorithm) {
  434. super(algorithm);
  435. this.kpairGenSpi = kpairGenSpi;
  436. }
  437. // engine method
  438. public void initialize(int keysize, SecureRandom random) {
  439. kpairGenSpi.initialize(keysize, random);
  440. }
  441. // engine method
  442. public void initialize(AlgorithmParameterSpec params,
  443. SecureRandom random)
  444. throws InvalidAlgorithmParameterException {
  445. kpairGenSpi.initialize(params, random);;
  446. }
  447. // engine method
  448. public KeyPair generateKeyPair() {
  449. return kpairGenSpi.generateKeyPair();
  450. }
  451. }
  452. }